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.
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 togetBaseUrl() + actionDefinition=reverse(...)and
String getBaseUrl()is defined asapplication.baseUrlONLY IF there’s no request – otherwise it usesHttp.Request.current().getBase().ActionDefinition.absoluteuses a bunch of variables from thereverseresult.In 1.2.3 code:
reverseabsoluteThe
@@tag basically uses: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…