Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

request.url does not seem to include the prefix or version #174

Closed
dvandersluis opened this issue May 16, 2012 · 3 comments
Closed

request.url does not seem to include the prefix or version #174

dvandersluis opened this issue May 16, 2012 · 3 comments

Comments

@dvandersluis
Copy link

As part of the authentication scheme for my API, the URL the consumer accessed is hashed as part of an authentication token. However, when I access request.url in my authentication code, the API prefix and the API version specified are not reflected in the URL:

class API < Grape::API
  error_format :json

  use API::Auth, :token_class => "ApiToken"

  version 'v1', :using => :path
  prefix 'api'

  resources :employees do
    get do
      Employee.all
    end
  end
end

If I GET /api/v1/employees.json, request.url is set to http://www.example.com//employees (note the double slash). Since the consumer, however, is (properly) using http://www.example.com/api/v1/employees as the URL, the URL on each side does not match up and authentication fails.

Any ideas how to fix or get around this?

@dvandersluis
Copy link
Author

If I remove the version and prefix, and mount the API at "/api" rather than at "/", request.url does get set properly, but I'm not sure if there are any other issues that this will cause.

@dblock
Copy link
Member

dblock commented May 28, 2012

I can confirm this is a bug. We should probably fix it, but I am not sure how (spec/grape/endpoint.spec).

  context 'request' do
    it 'should be set to the url requested' do
      subject.get('/url') do
        request.url
      end
      get '/url'
      last_response.body.should == "http://example.org/url"
    end
    it 'should include version' do
      subject.version 'v1', :using => :path
      subject.get('/url') do
        request.url
      end
      get '/v1/url'
      last_response.body.should == "http://example.org/v1/url"
    end
    it 'should include prefix' do
      subject.version 'v1', :using => :path
      subject.prefix 'api'
      subject.get('/url') do
        request.url
      end
      get '/api/v1/url'
      last_response.body.should == "http://example.org/api/v1/url"
    end
  end

The request is constructed from RACK ENV in base.rb like this:

def request
   Rack::Request.new(self.env)
end

Here the middlware probably needs to be self-aware that it's mounted under a specific path and version and method and transform PATH_INFO inside that self.env value into the full path. But it sounds complicated, there's got to be a way to get the origin HTTP request path and pass it around.

In the short term, you can get the current route information via route, for my second example above the route will have "version=v1, method=GET, path=/:version/url(.:format)".

@dblock dblock closed this as completed in b44cd8d Jan 5, 2013
@dblock
Copy link
Member

dblock commented Jan 5, 2013

This has been fixed. Path versioning was modifying env['PATH_INFO'], which it shouldn't.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants