I am trying to implement the work around suggested on this link
http://raibledesigns.com/rd/entry/how_to_do_cross_domain
My existing Servlet on my server looks like
#SuppressWarnings("serial")
public class ContactsServiceImpl extends RemoteServiceServlet implements ContactsService
{
...
How do I modify this to get the cross domain to work. Do I need to make any changes on the client side?
It isn't the GWT Same Origin Policy - it is the browser itself! The browser won't normally allow any XHR call to go out to a server that isn't the same server the page was loaded from.
The link you mentioned lets your server act as a proxy - thats one way to let the client talk to another server. The steps they take (create a servlet that forwards requests, configure it to point at the other server you want to use) do not require changes to the client.
Another option is to use the Cross Origin Resource Sharing - a way for the server to specify that the browser is allowed to contact it, even across domains. The catch: not all browsers support it.
Related
Is it possible to override a single API end-point locally?
i.e:
https://jsonplaceholder.typicode.com/todos/1
To this one:
http://localhost:3000/todos/1
But without touching others end-point like:
https://jsonplaceholder.typicode.com/movie/1
I'm trying to find a tool to do this, I also tried to use the hosts file but it work only domain by domain, not for a single API endpoint.
You can use the Map Remote function in Charles. I believe similar feature exists in other HTTP proxy tool such as Fiddler too.
First, configure Map Remote and mapping https://jsonplaceholder.typicode.com to http://localhost:3000, limit the path to /todos/*, so that it won't impact /movie/1:
Then, as Charles is trying to intercept HTTPS site, you need to enable "SSL Proxying" and add jsonplaceholder.typicode.com (Otherwise, browser will ignore the interceptor or just throw a certificate warning):
It's done. In browser, access to https://jsonplaceholder.typicode.com/todos/1 or https://jsonplaceholder.typicode.com/todos/2 will be redirected to http://localhost:/todos/1 or http://localhost:3000/todos/2 internally, while access to https://jsonplaceholder.typicode.com/movie/1 is not touched.
I want to 301 redirect the URLs from previous site that are nested, as pencilblue doesn’t support them,
e.g. a/b to page/b
For this I have been experimenting in include/http/request_handler.js but facing some issues.
Call never comes inside RequestHandler.prototype.handleRequest or even RequestHandler.prototype.onSessionRetrieved (seems these methods are not being called from anywhere)
Therefore I placed the code in RequestHandler and after confirming that req is not for public resource or api, I create a new url and execute
return this.doRedirect(newUrl, 301)
This actually works but at the same time I receive
Can’t render headers after they are sent error
#1075 has not helped me much as I’m not sure which specific controller I should modify. I need to catch the req as early as possible and see if it’s a page then redirect to page prefixed url.
Thanks in advance.
There are couple of ways to do redirects. You can do them from a controller or from middleware. You are correct in that, some of the functions in the request handler are not called. These are deprecated despite the fact pencilblue team didn't mark them as such. They replaced a good deal of the request handler functionality with /include/http/router.js and include/http/middleware/index.js. Plugins can register their own middleware to hijack the request pipeline.
See Advanced Routing on wiki for more info about creating your own middleware.
Using the routing framework your plugin would be able to register middleware that would be able to inspect the request and then redirect based on your specific criteria. The Router will be accessible from req.router and from there you could call req.router.redirect (Source).
Reference: #1224
Assume that I have a website whose static assets are hosted in CDN (say, AWS CloudFront), however, all the GWT-RPC calls will be handled in the domain hosts. How can I achieve this in GWT?
As #robert mentioned, CORS is another option, but it doesn't require any changes in your client-side code - if the browser is new enough to support CORS at all, then all you do is make the call to the remote server, and make sure that the remote server supports it.
Depending on which server you are using, the support will be slightly different. https://www.w3.org/wiki/CORS_Enabled has a list of different servers and how you might enable CORS, depending on what you are using, and whether you enable it across your entire server, or just in a single part of the application.
For example, in Jetty:
<filter>
<filter-name>cross-origin</filter-name>
<filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cross-origin</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
While in Tomcat:
CorsFilter
org.apache.catalina.filters.CorsFilter
CorsFilter
/*
It is also possible to modify your RemoteServiceServlet class to handle this, but it comes with the disadvantage of needing to more fully understand the spec and make sure you handle it all correctly.
As with JSONP, there are important security implications of allowing cross-domain requests. Unlike JSONP, the CORS spec includes features to mitigate this, and ensure that the browser doesn't attempt to make calls to your remote server from the wrong host page - you can restrict calls so that they only come from specific domains. The specific header is Access-Control-Allow-Origin, and while it can be assigned to *, meaning "all servers", you likely want to restrict it to avoid potential XSRF attacks against your application - for the above examples this is managed via init-parameters, check your container's documentation for specific details. Additionally, changing the url-pattern can restrict the urls that these filters apply to can limit what can be requested remotely.
You could try to use CORS (https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS)
Something like this:
public class CrossSiteRpcRequestBuilder extends RpcRequestBuilder {
#Override
protected RequestBuilder doCreate(String serviceEntryPoint) {
RequestBuilder requestBuilder=super.doCreate(serviceEntryPoint);
requestBuilder.setIncludeCredentials(true);
return requestBuilder;
}
}
public class CrossSiteRpcRequestBuilderFactory {
public RpcRequestBuilder get() {
return new CrossSiteRpcRequestBuilder();
}
}
RpcRequestBuilder rpcRequestBuilder=((CrossSiteRpcRequestBuilderFactory) GWT.create(CrossSiteRpcRequestBuilderFactory.class)).get();
rpcRequestBuilder.create("{YOUR_HOST}/cors_handshake");
rpcRequestBuilder.setContentType("text/x-gwt-rpc; charset=utf-8");
rpcRequestBuilder.setRequestData("cors handshake");
rpcRequestBuilder.setCallback(new RequestCallback() {
...
});
RequestBuilder r=rpcRequestBuilder.finish();
r.send();
An alternative would be to use your server as a proxy to the remote server (bandwidth).
In conclusion:
I would use JsonpRequestBuilder instead of RPC, its less convenient, but guaranteed to work (unlike CORS).
See http://www.gwtproject.org/doc/latest/tutorial/Xsite.html for details.
I need to include some secure (BASIC authentication) application.
when I open the application URL in the browser, the browser asks me to enter your credentials ...
what I know is that:
The browser ask the server to get
some URL -- the url of the app
The server checks the request header
for the Authentication header and
didn't find it
The server sends 401 to the
browser back
The browser interpret this response
code into a message dialog that
shows to me asking me to enter the
username/password to send back to
the server in the Authentication
request header
So far... so good, I can write some page (in JSP) that send this required http request header to the request that is calling this page..
So I'll call this application through my page..
The problem here is, this application (in fact a GWT application) contains a reference to some Javascript and CSS files that is coming from the server that hosts this application. the application page that I import looks like:
<html>
<link href="http://application_host/cssfile.css" />
<link href="http://application_host/javascriptfile.js" />
.....
</html>
So, again I found the application asks me for the authentication crenditals for the css and js files!
I am thinking of many solutions but don't know the applicability of each
One solution is to ask the browser
(via Javascript) to send the request
header (Authentication) when he
asks the server for the js and css
files
please give me your opinions about that... and any other suggestions will be very welcomed.
Thanks.
I think you're running into some weirdness with how your server is configured. Authentication happens in context of a authentication realm. Your assets should either be in the same authentication realm as your page, or (more likely) should not require authentication at all. The browser should be caching credentials for the given realm, and not prompt for them again.
See the protocol example on http://en.wikipedia.org/wiki/Basic_access_authentication
Judging from your story, something tells me your problem is with the authentication method itsef. Not how to implement it. Why do you want to bother with the request header so much?
As far as i know, you can configure your container (ie Tomcat) to force http authentication for certain urls. Your container will make sure that authentication has taken place. No need to set http headers yourself whatsoever.
Perhaps you can explain a bit better what you are trying to achieve, instead of telling implementation details?
Why css & js files are kept in protected area of server? You need to place files into public area of your server. If you don't have public area, so you nead to prpvide for it. how to do it depends from serverside software architecture & configuration.
Why does using Fiddler break my site sometimes on page transitions.
After a server side redirect -- in the http response (as found in Fiddler) I get this:
Object moved
Object moved to here.
The site is an ASP.NET 1.1 / VB.NET 1.1 [sic] site.
Why doesnt Fiddler just go there for me? i dont get it.
I'm fine with this issue when developing but I'm worried that other proxy servers might cause this issue for 'real customers'. Im not even clear exactly what is going on.
That's actually what Response.Redirect does. It sends a 302 - Object moved response to the user-agent. The user-agent then automatically goes to the URL specified in the 302 response. If you need a real server-side redirect without round-tripping to the client, try Server.Transfer.
If you merely constructed the request using the request builder, you're not going to see Fiddler automatically follow the returned redirect.
In contrast, if you are using IE or another browser, it will generally check the redirect header and follow it.
For IE specifically, I believe there's a timing corner case where the browser will fail to follow the redirect in obscure situations. You can often fix this by clicking Tools / Fiddler Options, and enabling both the "Server" and "Client" socket reuse settings.
Thanks user15310, it works with Server.Transfer
Server.Transfer("newpage.aspx", true);
Firstly, transferring to another page using Server.Transfer conserves server resources. Instead of telling the browser to redirect, it simply changes the "focus" on the Web server and transfers the request. This means you don't get quite as many HTTP requests coming through, which therefore eases the pressure on your Web server and makes your applications run faster.
But watch out: because the "transfer" process can work on only those sites running on the server, you can't use Server.Transfer to send the user to an external site. Only Response.Redirect can do that.
Secondly, Server.Transfer maintains the original URL in the browser. This can really help streamline data entry techniques, although it may make for confusion when debugging.
That's not all: The Server.Transfer method also has a second parameter—"preserveForm". If you set this to True, using a statement such as Server.Transfer("WebForm2.aspx", True), the existing query string and any form variables will still be available to the page you are transferring to.
Read more here:
http://www.developer.com/net/asp/article.php/3299641/ServerTransfer-Vs-ResponseRedirect.htm