Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play! framework : what is the difference between Router.getFullUrl("action") and Router.reverse("action").absolute()?

I need an absolute URL on my Play! 1.2.4 application as a callback for an OAuth authentication (using Scribe.

My application is running behind an Apache virtual proxy, to be accessible through an URL with subdomain like "http://myapp.mydomain.com", proxying "http://127.0.0.1:9000". ProxyPreserveHost is set to On. In my Play! application configuration, I have the following property : application.baseUrl=http://myapp.mydomain.com/.

To compute this absolute URL, I used a piece of code like :

Router.ActionDefinition ad = Router.reverse("Controller.callback");
ad.absolute();
return ad.url;

This code worked fine with Play! 1.2.3 : it returned "http://myapp.mydomain.com/callback".

Now that I use Play! 1.2.4, this code now returns "http://www.mydomain.com:9000/callback" (translated URL by the virtual proxy without subdomain), as if Play! now used HTTP request's URL to build this absolute URL.

I empirically replaced this code to Router.getFullUrl("Controller.callback"), which fixes my issue.

Those two methods Router.getFullUrl() and Router.absolute() are not documented (booo!), and I was wondering the subtle differences to understand my issue. I suppose that Router.absolute() uses current HTTP request to build absolute URL, and Router.getFullUrl() uses application.baseUrl configuration property. I also may have an Apache configuration issue (as it is clearly not one of my skills!), but with ProxyPreserveHost set to On, I assumed that my virtual proxy would be transparent to Play! application, and I don't understand why it appears when switching from Play! 1.2.3 to 1.2.4.

Thanks for your help.

like image 347
Cyril Lacôte Avatar asked Oct 10 '22 00:10

Cyril Lacôte


1 Answers

You got me curious so I went looking into the code (click to see the relevant functions directly in github). And I agree that Play! documentation is far from complete :), actually code would benefit of some more javadocs!

Some more tests

In any case, this might be a bug... or a misuse!, there's a couple of tests you should do:

One thing you should try is the template absolute notation: @@{…}. Most of the time you do not need to reverse urls in your code, just in templates. Is that correct or not?

Did you try Router.reverse("action", true) ?

And what happens if you access directly the "localhost:9000" url from your browser, with all the different 'absolute' options?

The code

In the 1.2.4 code:

String getFullUrl(...) is simply equal to getBaseUrl() + actionDefinition=reverse(...)

and String getBaseUrl() is defined as application.baseUrl ONLY IF there's no request - otherwise it uses Http.Request.current().getBase().

ActionDefinition.absolute uses a bunch of variables from the reverse result.

In 1.2.3 code:

reverse

absolute

The @@ tag basically uses:

private String __reverseWithCheck(String action, boolean absolute) {
    return Router.reverseWithCheck(action, Play.getVirtualFile(action), absolute);
}

with absolute true, that is calling directly reverse(action, absolute=true) but receiving a string rather than an ActionDefinition

Conclusions

Maybe some play developer will step in... but i tried to help a bit, and learn in the process :) I'll let you step into the full details of comparing the two functions, but they have quite a different approach in deliverying an abs. url...

like image 134
Stefano Avatar answered Oct 13 '22 10:10

Stefano