whichdigital / active-rest-client

ActiveRestClient API Client
https://rubygems.org/gems/active_rest_client
MIT License
385 stars 44 forks source link

Bad URI(is not URI?) #94

Closed samuelcouch closed 9 years ago

samuelcouch commented 9 years ago

I currently have my model as such:

class Item < ActiveRestClient::Base
  base_url "http://api.my-url.com/v2"
  username 'username'
  password 'password'

  get :all, "/list/"
  get :find, "/items/:id"
end

When I query Item.all within rails console, I get the following error

>> Item.all
  ActiveRestClient Item:/list - Trying to read from cache
  ActiveRestClient (3.9ms) Item#all
URI::InvalidURIError: bad URI(is not URI?): http://username:password@api.my-url.com

Any idea how to resolve this? It's curious to me how the v2 is being dropped in the error, even though it's in my base_url

andyjeffries commented 9 years ago

I assume this is a simplified example, rather than the real one. Because it "works" for me...

$ gem install active_rest_client
Fetching: active_rest_client-1.0.9.gem (100%)
Successfully installed active_rest_client-1.0.9
1 gem installed
$ irb
irb(main):001:0> require 'rubygems'
=> false
irb(main):002:0> require 'active_rest_client'
=> true
irb(main):003:0> class Item < ActiveRestClient::Base
irb(main):004:1>   base_url "http://api.my-url.com/v2"
irb(main):005:1>   username 'username'
irb(main):006:1>   password 'password'
irb(main):007:1> 
irb(main):008:1*   get :all, "/list/"
irb(main):009:1>   get :find, "/items/:id"
irb(main):010:1> end
=> :lazy_find
irb(main):011:0> Item.all
ActiveRestClient::HTTPNotFoundClientException: ActiveRestClient::HTTPNotFoundClientException

Obviously I hit some poor guy's server (on my-url.com) so got a 404, to be expected.

So it sounds like there's something wrong with your base_url.

The reason the v2 is being dropped from parsing is that the final URL (with /list on the end) is split in to the hostname/port and everything before it; and the path with any params so the connection can be made. So the URL parsing is only done on everything up to the hostname/port, then the path and query string is sent as-is to the server. So that's expected and correct behaviour.

samuelcouch commented 9 years ago

Some poking around, I tried removing the username and password items, and it likes the URL, and I get a Not Authorized (as expected). So I think that I've isolated that it doesn't like parsing the http://username:password@base_url -- however, if I Curl that URL, with one of my endpoints, I get a data response like I expect (so I know it works). Is it possible that since my username contains an @ symbol, it's throwing off the parsing?

andyjeffries commented 9 years ago

Try encoding the username as containing a %40 instead of @.

samuelcouch commented 9 years ago

That did the trick! Thanks so much.

andyjeffries commented 9 years ago

Actually, I'll keep the issue open and at some point do it so it automatically encodes the username/password (unless they already contain a % character).

andyjeffries commented 9 years ago

Fixed in 5310389862c10b49e05cba4cf1b80d8fdac4fb29 (released as v1.1.0)