Play 2 javascript routing with https - nginx

I'm using play's javascript routing (http://www.playframework.com/documentation/2.2.x/ScalaJavascriptRouting). I have a nginx front-end server, which I configured to force https.
When I try to make an ajax call, I get an error, since the javascript routing generates http urls and my browser blocks them because of cross origin access.
How can I configure the javascript routing to serve https urls?

How are you making the calls? The Play JavaScript router returns objects with two properties, one is a method property which contains the method, eg POST, GET etc. The other is a url property which contains the relative URL.
There are also two methods on the returned object, one called absoluteURL, the other called webSocketURL. These will return absolute URLs according the hostname of the current page, and they will be http or https (or ws or wss) based on whether the current page is secure or not.
So, if using with jQuery for example, you should be able to just:
$.ajax(jsRoutes.controllers.MyController.myAction("foo")).then(...)
And it will use the relative URL, or you can also:
var route = jsRoutes.controllers.MyController.myAction("foo")
$.ajax({
method: route.method,
url: route.url,
...
}).then(...)

If you're trying to make that requests using absolute urls, Hostnames, protocols and ports should match because of same-origin policy. You have at least two options:
Use relative urls on ajax requests like href="/your/page"
Use the protocol relative url's. Example: href="//your.domain.com/your/page.
Here is a detailed article by Paul Irish about protocol relative url's:
http://www.paulirish.com/2010/the-protocol-relative-url/

You have to pass it as a parameter to absoluteURL/websocketURL.
Frome Chrome dev tools:
> jsRoutes.controllers.CalendarController.getEvents().absoluteURL
function (s){return _s('http',s)+'localhost:9000'+r.url}
> jsRoutes.controllers.CalendarController.getEvents().absoluteURL()
"http://localhost:9000/events"
> jsRoutes.controllers.CalendarController.getEvents().absoluteURL(true)
"https://localhost:9000/events"
> jsRoutes.controllers.CalendarController.getEvents().webSocketURL
function (s){return _s('ws',s)+'localhost:9000'+r.url}
> jsRoutes.controllers.CalendarController.getEvents().webSocketURL()
"ws://localhost:9000/events"
> jsRoutes.controllers.CalendarController.getEvents().webSocketURL(true)
"wss://localhost:9000/events"
_s is defined at https://github.com/playframework/playframework/blob/master/framework/src/play/src/main/scala/play/api/routing/JavascriptReverseRouter.scala#L54 as
function(p,s){return p+((s===true||(s&&s.secure))?'s':'')+'://'}

Related

Apigee rest endpoint path mapping to custom path

I have rest end point /admn_resource_manager.I have created a apigee proxy to expose this.
I dont want to expose it like this to others as I want something like /adminmanager.
Is there any way to map /adminmanager to /admn_resource_manager using Apigee.
end user would use http://someurl.apigee/adminmanager instead of http://someurl.apigee/admn_resource_manager
I explored KeyValueMapoperation and AssignMessage in Apigee.
I am not sure if these are the right option to implement map path.I didn't get any example for this either.
The way you would think to do this would be to use the Assign Message policy and use the Set -> Path element. But this policy isn't currently working as designed for rewriting the proxy's target URL. See the Assign Message Guidance for more details.
To rewrite the incoming URL to a different target URL you can use the Assign Message Policy to set the entire URL (target.url) in the Target Endpoint flow, or you can use a JavaScript callout to set it. I chose to use a JavaScript callout because it gives a lot more control when rewriting the URL.
Here is an example project on Github I put together for this you can use to see how I did it. It uses the swapi.co api as the target endpoint. This proxy uses the Assign Message and JavaScript callout policies to rewrite the URL. Here's some details about it...
Proxy Endpoints
Create a proxy endpoint for each resource you are renaming.
This is where you setup the Assign Message policy to set the variables for the new path suffix.
Assign Message Policies
Set on the PreFlow of each proxy endpoint to set the targetPathSuffix and appendResourceIdToUrl (if needed) variables.
JavaScript Policy
Calls out to the URLRewrite.js file to execute the js code.
Set on the TargetEndpoints PreFlow and executes on each request
Uses the variables set in the Assign Message Policies to change the target.url variable.
I think Apigee can do it.
When I was started Apigee I have learned and try to understand from the picture below. (I think it is describe the main concept of this platform)
From your scenario,
You can specify the URL that you wants client to call maybe someurl.apigee/adminmanager or something else
Apigee is a middle also known as a Gateway. When you received the request from client, you can manage whatever you want. Of course, including pass your client to other URL like someurl.apigee/admn_resource_manager . (You just assigned new url to that request)
Because I'm not an expert as well so, you this link below can explain you more information.
Link:Using Flow Variables

Symfony2: Dynamically generate URL protocol (HTTP/HTTPS)

I know many ways of forcing a route or a whole section to use either http or https:
http://symfony.com/doc/current/cookbook/routing/scheme.html
http://symfony.com/doc/current/cookbook/security/force_https.html
How to let Symfony 2 adopt the protocol scheme (http vs https)
...my question is: Is there a way for it to be decided dynamically?
By this, I mean, when I generate the url {{url('route_name'}} it generates a URL using the same protocol that the current page is using.
http://domain/index links to http://domain/route
https://domain/index links to https://domain/route

Difference Between // and http://

I know that HTTP is hyper text transfer protocol, and I know that's how (along with HTTPS) one accesses a website. However, what does just a // do? For instance, to access Google's copy of jQuery, one would use the url //ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js, as opposed to http://....
What exactly is the difference? What does just // indicate?
Thanks.
By saying on // it means use whatever protocol (IE: http vs https) your user is currently hittin for that resource.
So you don't have to worry about dealing with http: vs https: management yourself.
Avoiding potential browser security warnings. It would be good practice to stick with this approach.
For example: If your user is accessing http://yourdomain/ that script file would automatically be treated as http://ajax.googleapis.com/...
if your current request is http
//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js
will be treated as
http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js
if your current request is https
//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js
will be treated as
https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js

AngularJS routing hides 404 responses for nonexistent routes

I have noticed that GET requests for nonexistent paths don't return a 404 response. Instead, the client gets a "200 Ok", AngularJS renders the main view, and rewrites the path to /. A request for a nonsense URI is logged as successful in the server logs. If I understand correctly, the problem is that since AngularJS handles routing, the server has to accept a GET request for any URI and always respond by serving the client side of the app ("200 Ok" or "304 Not Modified").
For example, using the project scaffolded by the angular-fullstack Yeoman generator, requesting a nonexistent /unicorn goes like this:
GET /unicorn 200 31ms - 3.29kb
GET /partials/main 304 36ms
GET /api/awesomeThings 304 5ms
The Express route that handles the request looks like this:
// server, last route:
app.get('*', controllers.index);
// controllers:
exports.index = function(req, res) {
res.render('index');
};
and index.jade is the root of the whole client side of the app.
After a quick look at the server side code of other AngularJS / Express projects on Github (AngularJS Express seed, AngularJS login), I see that this is a common pattern. I am wondering if there is a better way to handle requests for nonexistent paths, so that the client gets a real HTTP 404 response?
The angular documentation has a section about the routing. Also, this question and this question have some information that pertains to IIS but could easily be adapted to express.
Html link rewriting
When you use HTML5 history API mode, you will need different links in different browsers, but all you have to do is specify regular URL links, such as: link
When a user clicks on this link,
In a legacy browser, the URL changes to /index.html#!/some?foo=bar
In a modern browser, the URL changes to /some?foo=bar
In cases like the following, links are not rewritten; instead, the browser will perform a full page reload to the original link.
Links that contain target element
Example: link
Absolute links that go to a different domain
Example: link
Links starting with '/' that lead to a different base path when base is defined
Example: link
When running Angular in the root of a domain, along side perhaps a normal application in the same directory, the "otherwise" route handler will try to handle all the URLs, including ones that map to static files.
To prevent this, you can set your base href for the app to <base href="."> and then prefix links to URLs that should be handled with .. Now, links to locations, which are not to be routed by Angular, are not prefixed with . and will not be intercepted by the otherwise rule in your $routeProvider.
Server side
Using this mode requires URL rewriting on server side, basically you have to rewrite all your links to entry point of your application (e.g. index.html)
You can use $route.otherwise() function
In order to decide what to do with undefined
Routes.
If you want to still show a 404 message,
You could simply set a /404.html route both in this Function and in express.
This is actually express handling routing--not angular. Remove the app.get('*', ... that you found to disable that.

HTTP redirection without updating document.location

We have a service located at a url like services.example.com/123456/*. We'd like to provide that same service at a url like www.example.com. The original service is provided by a PaaS provider which doesn't work with custom domains.
We want a request to go something like this: browser requests www.example.com/path, we tell it to go to services.example.com/123456/path, and it gets the data from there, but treats the response as if it came from www.example.com/path - so doesn't update document.location or the url at the top, and treats links as relative to the original path.
Is this possible, or would we have to have a own proxy-like website?
You need a proxy that do url rewriting.

Resources