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

selfLink doesn't behave correctly with Cross-site baseurls #493

Open
aarcro opened this issue Dec 20, 2013 · 12 comments
Open

selfLink doesn't behave correctly with Cross-site baseurls #493

aarcro opened this issue Dec 20, 2013 · 12 comments
Labels

Comments

@aarcro
Copy link

aarcro commented Dec 20, 2013

I'm serving my Angular app from localhost:8000, with django running a tastypie backend on localhost:8888. I'm simulating a mobile app, so I have no need or desire to have django server the angular app.

With a config like this:

RestangularProvider.setBaseUrl('http://localhost:8888/api/v1/');  // Following the bing example
RestangularProvider.setRestangularFields({
  selfLink: 'resource_uri'
});

and resoure_uri values, which look like: "/api/v1/object/id"

The generated path when trying to put is:
http://localhost:8888/api/v1//api/v1/object/id

Perhaps BaseUrl should be split to BasePath and BaseDomain?

@aarcro
Copy link
Author

aarcro commented Dec 20, 2013

Also, this doesn't work:

    var site_address = "http://localhost:8888";
    console.log('Put from here:' + site_address + obj.resource_uri);
    return obj.customPUT(site_address + obj.resource_uri);

the correct address is logged, but the customPUT still goes to localhost:8000 :(

@aarcro
Copy link
Author

aarcro commented Dec 20, 2013

Not the best way to submit a patch, I know, but I did this:

        /**                                                                                                                                                                                          
         * This is the BaseURL to be used with Restangular                                                                                                                                           
         */                                                                                                                                                                                          
        config.baseUrl = _.isUndefined(config.baseUrl) ? "" : config.baseUrl;                                                                                                                        
        object.setBaseUrl = function(newBaseUrl) {                                                                                                                                                   
            config.baseUrl = /\/$/.test(newBaseUrl)                                                                                                                                                  
              ? newBaseUrl.substring(0, newBaseUrl.length-1)                                                                                                                                         
              : newBaseUrl;                                                                                                                                                                          

            // grab the protocol, domain and port                                                                                                                                                    
            config.baseDomain =  absolutePattern.test(newBaseUrl)                                                                                                                                    
              ? config.baseDomain = newBaseUrl.match(/^https?:\/\/[^\/]*/i)                                                                                                                          
              : '';                                                                                                                                                                                  
            return this;                                                                                                                                                                             
        };                                                                                                                                                                                           

And this:

                if (elemSelfLink) {                                                                                                                                                                  
                  if (__this.config.isAbsoluteUrl(elemSelfLink)) {                                                                                                                                   
                    return __this.config.baseDomain + elemSelfLink;                                                                                                                                  
                  } else {                                                                                                                                                                           
                    elemUrl = elemSelfLink;                                                                                                                                                          
                  }                                                                                                                                                                                  

Hope that points you in the right direction. It seems to be working for me at the moment. Actually I can see that it would break elemSelfLink values that started with http://

@mgonto
Copy link
Owner

mgonto commented Dec 24, 2013

Hey,

Answering by parts:

Also, this doesn't work:

var site_address = "http://localhost:8888";
console.log('Put from here:' + site_address + obj.resource_uri);
return obj.customPUT(site_address + obj.resource_uri);

the correct address is logged, but the customPUT still goes to localhost:8000 :(

If you need to do a put to a custom URL, you should use oneUrl or allUrl. Something like Restangular.oneUrl('people', 'http://locahost:8888/people/name/123').customPUT(objectToPut). However, if it's going to locallhost, you should use "normal" Restangular behaviour.

and resoure_uri values, which look like: "/api/v1/object/id"

The generated path when trying to put is:
http://localhost:8888/api/v1//api/v1/object/id

Perhaps BaseUrl should be split to BasePath and BaseDomain?

Does this happen with the latest version of Restangular? I've fixed some problems with self linking elements in version 1.2.2. If that's not working, I'll mark this as a bug and check it out.

Thanks!

@mgonto mgonto closed this as completed Jan 14, 2014
@jsmpereira
Copy link

Hi @mgonto,
Thanks for all your work on restangular.

I'm running into similar behavior.

Configuration:

RestangularProvider.setBaseUrl("http://localhost:3000")

RestangularProvider.setSelfLinkAbsoluteUrl("http://localhost:3000")

RestangularProvider.setRestangularFields
  selfLink: '_links.self.href' # HAL self link

When trying to retrieve posts from a user it fails to honour the baseUrl.
The path is correct though, looking like the selfLink is behaving correctly.

The request goes to the nodejs server that is serving my app, instead of the api server.

Restangular.all("users").getList().then (users) ->
  user = users[0]
  user.all("posts").getList().then (posts) ->
    $scope.posts = posts

I can make it work by commenting out https://github.com/mgonto/restangular/blob/master/src/restangular.js#L27 and changing
https://github.com/mgonto/restangular/blob/master/src/restangular.js#L645
to

return __this.config.absoluteUrl+elemSelfLink;

Cheers

@roxeteer
Copy link

This issue shouldn't be closed. It still exists in 1.3.1 and based on the release notes, the behaviour hasn't changed in 1.4.0.

I'm currently circumventing this the "hard way" in a responseInterceptor:

angular.module('myapp').run([
  'Restangular',
  function(Restangular) {
    'use strict';

    // Workaround for https://github.com/mgonto/restangular/issues/493
    // Part 1: Figure out the protocol, host and port of the base url
    var parser = document.createElement('a');
    parser.href = Restangular.configuration.baseUrl;
    var baseUrl = parser.protocol + '//' + parser.host;

    Restangular.addResponseInterceptor(function(data, operation, what, url, response, deferred) {
      if (operation === "getList") {
        // Workaround for https://github.com/mgonto/restangular/issues/493
        // Part 2: Update selfLinks to have the full URL with the host
        if (data.length && data[0].href) {
          data.forEach(function(item) {
            if (item.href && item.href[0] === '/') {
              item.href = baseUrl + item.href;
            }
          });
        }
      }

      return data;
    });
  }
]);

@mgonto mgonto reopened this May 31, 2014
@scottmcdonnell
Copy link

I have the same problem with this where the baseURL is ignored for self links.

Additionally I am getting an issue when the links include a format suffix such as /resource/id.json then a call to a sub resources is calling /resource/id.json/subresource instead of /resource/id/subresource.json.

Can the RequestSuffix be taking into account for the self links?

scottmcdonnell pushed a commit to scottmcdonnell/restangular that referenced this issue Jul 10, 2014
…ks and remove suffix

fixes issue mgonto#493 to add the selfLink absolute URL to the start of the
URLs for cross-site self links to work.
Also if there is a request suffix it will remove it from the selfLink to
allow for sub-resources to be referenced.
@scottmcdonnell
Copy link

Added pull request #785 as a suggestion to fix the above issues.

scottmcdonnell pushed a commit to scottmcdonnell/restangular that referenced this issue Jul 11, 2014
@RemoteCTO
Copy link

+1 for this. I've also used the dirty patch as in #493 (comment) in the meantime.

@cstephe
Copy link

cstephe commented Mar 12, 2015

I use delete Restangular.configuration.absoluteUrl; as a work around

@yusufumac
Copy link

This issue has been a long time wait (from 2013) and gaining PR in multiple issues. It would be great to increase the priority. Thanks

@daviesgeek
Copy link
Collaborator

If I'm understanding this correctly, this is addressed in #851?

@priiduneemre
Copy link

+1

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

No branches or pull requests

10 participants