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!
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?
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
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...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With