GWT Upload is not working in cross domain request - gwt

I am using GWTUplaod in my application which is working fine if I don't use cross domain.But it is not working correctly in cross domain scenario.
Let me explain,
GWT Server is at IP address 5.5.5.10 and GWT Client is at IP address 5.5.5.12 , earlier while uploading I was getting error in request due to cross domain then I override servlet doPost and doGetMethod
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
try {
FlowContextManager.getInstance().setFlowId(FlowContextManager.getNextFlowId());
processCrossDomainHeaders(request, response);
super.doGet(request, response);
} catch (Exception e) {
logger.error(e);
} finally {
FlowContextManager.getInstance().setFlowId("");
}
}
#Override
protected final void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException,
ServletException {
try {
FlowContextManager.getInstance().setFlowId(FlowContextManager.getNextFlowId());
processCrossDomainHeaders(request, response);
super.doPost(request, response);
} catch (Exception e) {
logger.error(e);
} finally {
FlowContextManager.getInstance().setFlowId("");
}
}
public void processCrossDomainHeaders(HttpServletRequest request, HttpServletResponse response) {
HttpServletResponse resp = response;
HttpServletRequest req = request;
String header = req.getHeader("Origin");
if (header != null) {
resp.addHeader("Access-Control-Allow-Origin", header);
}
resp.addHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
header = req.getHeader("Access-Control-Request-Headers");
if (header != null) {
resp.addHeader("Access-Control-Allow-Headers", header);
}
resp.addHeader("Access-Control-Max-Age", "100");
}
#Override
protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.addHeader("Access-Control-Allow-Origin", req.getHeader("Origin"));
resp.addHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
String header = req.getHeader("Access-Control-Request-Headers");
resp.addHeader("Access-Control-Allow-Headers", header);
resp.addHeader("Access-Control-Max-Age", "100");
super.doOptions(req, resp);
}
Now my GWTUploadServlet is extending this abstract servlet.
In my web.xml I have specified following entries
<servlet>
<servlet-name>uploadServlet</servlet-name>
<!-- This is the default servlet, it puts files in session -->
<servlet-class>com.drishti.ameyo.webclient.server.WebClientUploadServlet</servlet-class>
<init-param>
<param-name>corsDomainsRegex</param-name>
<param-value>.*</param-value>
</init-param>
</servlet>
I have referred following link
http://code.google.com/p/gwtupload/issues/detail?id=187
Request is getting successful but I am getting following error on browser console.
Blocked a frame with origin "http://10.10.10.192:8888" from accessing a frame with origin "http://10.10.10.250:8888". Protocols, domains, and ports must match. FormPanelImpl.java:32
onSubmitComplete: null SuperDevModeLogger.java:71
onSubmitComplete exception parsing response: SuperDevModeLogger.java:71
com.google.gwt.xml.client.impl.DOMParseException: Failed to parse: error on line 1 at column 1: Document is empty
at createStackTrace
at fillInStackTrace_1
at fillInStackTrace
at $fillInStackTrace
at Throwable_1
at Exception_1
at RuntimeException_1
at DOMException_1
at DOMParseException_0
at throwDOMParseException
at parseImpl_0
at $parse_3
at parse_3
at onSubmitComplete_0
at $dispatch_22
at dispatch_23
at dispatch
at dispatchEvent_1
I didn't get some good solution on it.Please help for it.

Related

Does Tomcat8 NIO2 protocol support Apache CometEvent?

How can I set the comet event timeout on NIO2 protocol?
How to well handle the socket connection on NIO2 protocol?(e.g., close connection)
We have a simple servlet which implements Apache CometEvent for long polling connection on tomcat8. It works well when we used org.apache.coyote.http11.Http11NioProtocol, however, we have now change to using org.apache.coyote.http11.Http11Nio2Protocol and it will not work properly.
On NIO, the client can make a comet connection to a Connect servlet by POST and the other client can send message by POST to Trigger servlet. Every 300 seconds we will timeout the comet and the client app will make comet connection again.
The Connect servlet as below
public class Connect extends HttpServlet implements CometProcessor {
...
public void event(CometEvent event) throws IOException, ServletException {
HttpServletRequest request = event.getHttpServletRequest();
HttpServletResponse response = event.getHttpServletResponse();
if (event.getEventType() == CometEvent.EventType.BEGIN) {
String deviceid = request.getParameter("id");
MessageSender.getInstance().addConnection(deviceid, event);
request.setAttribute("org.apache.tomcat.comet.timeout", 300 * 1000);
event.setTimeout(300 * 1000);
} else if (event.getEventType() == CometEvent.EventType.ERROR) {
MessageSender.getInstance().removeConnection(event);
event.close();
} else if (event.getEventType() == CometEvent.EventType.END) {
MessageSender.getInstance().removeConnection(event);
event.close();
} else if (event.getEventType() == CometEvent.EventType.READ) {
throw new UnsupportedOperationException("This servlet does not accept data");
}
}
}
And we have another Trigger servlet for sending message to client:
public class Trigger extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
byte[] receieveByteArray = ByteUtil.getHttpServletRequestBody(req);
sendTrigger(req, resp, receieveByteArray);
}
private void sendTrigger(HttpServletRequest req, HttpServletResponse resp, byte[] trigger) throws IOException, ServletException
{
try
{
MessageSender.getInstance().sendTrigger(deviceId, trigger);
} catch (Exception e)
{
logger.error("Send trigger has thrown exception: ", e);
}
}
}
And the MessageSender class as below
public class MessageSender
{
private static final Map<String, CometEvent> connections = new ConcurrentHashMap<String, CometEvent>();
public void addConnection(String deviceId, CometEvent event) {
connections.put(deviceId, event);
}
public void removeConnection(CometEvent event) {
while (connections.values().remove(event)) {
}
public static MessageSender getInstance() {
return instance;
}
public void sendTrigger(String deviceId, byte[] triggerMessage) throws IOException, ConnectionNotFoundException {
CometEvent comet = connections.get(deviceId);
HttpServletResponse response = comet.getHttpServletResponse();
response.addHeader("Content-Length", Integer.toString(triggerMessage.length));
response.addHeader("Content-Language", "en-US");
ServletOutputStream servletOutputStream = response.getOutputStream();
servletOutputStream.write(triggerMessage);
servletOutputStream.flush();
servletOutputStream.close();
comet.close(); // add for NIO2
connections.remove(deviceId);
}
}
After we have changed the connector setting of tomcat http protocol to NIO2 as below
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" connectionTimeout="60000"
keystoreFile="D:\localhost.jks" keystorePass="******" />
The timeout of event will not work as we have set it to 300 seconds, the comet connection will be disconnected after 60 seconds which I believe is the connector connection timeout. And there will have thrown an exception as below
28-Oct-2016 15:04:33.748 SEVERE [http-nio2-8443-exec-5] org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process Error reading request, ignored
java.lang.IllegalStateException: Reading not allowed due to timeout or cancellation
at sun.nio.ch.AsynchronousSocketChannelImpl.read(AsynchronousSocketChannelImpl.java:249)
at sun.nio.ch.AsynchronousSocketChannelImpl.read(AsynchronousSocketChannelImpl.java:297)
at org.apache.tomcat.util.net.SecureNio2Channel.read(SecureNio2Channel.java:792)
at org.apache.tomcat.util.net.Nio2Endpoint.awaitBytes(Nio2Endpoint.java:871)
at org.apache.coyote.http11.Http11Nio2Protocol$Http11ConnectionHandler.release(Http11Nio2Protocol.java:180)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:722)
at org.apache.tomcat.util.net.Nio2Endpoint$SocketProcessor.doRun(Nio2Endpoint.java:1073)
at org.apache.tomcat.util.net.Nio2Endpoint$SocketProcessor.run(Nio2Endpoint.java:1032)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
If the client make the comet connection again after this, and the other client try to send message to Trigger servlet. The comet will be END immediately and connection disconnected.
Any help is appreciated

Twitter object is always null I have taken example from twitter4j

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
TwitterFactory twitterFac = new TwitterFactory();
Twitter twitter = twitterFac.getInstance();
twitter.setOAuthConsumer("key", "secret");
request.getSession().setAttribute("twitter", twitter);
try
{
RequestToken requestToken = twitter.getOAuthRequestToken("http://local.your-domain.com:8080/sign-in-with-twitter/callback");
request.getSession().setAttribute("requestToken", requestToken);
System.out.println(requestToken.getAuthenticationURL());
response.sendRedirect(requestToken.getAuthenticationURL());
} catch (TwitterException e)
{
throw new ServletException(e);
}
}
}
****Then the twitter page redirects to a page of my application (CallbackServlet). All this is performed correctly.****
Then the CallbackServlet has the following doGet method:
public class CallbackServlet extends HttpServlet {
private static final long serialVersionUID = 1657390011452788111L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Twitter twitter = (Twitter) request.getSession().getAttribute("twitter");
RequestToken requestToken = (RequestToken) request.getSession().getAttribute("oauth_token");
String verifier = request.getParameter("oauth_verifier");
try {
twitter.getOAuthAccessToken(requestToken, verifier);
request.getSession().removeAttribute("requestToken");
} catch (TwitterException e) {
throw new ServletException(e);
}
response.sendRedirect(request.getContextPath() + "/");
}
}
=============================
The CallbackServlet tries to get the twitter and requestToken saved in the LoginServlet (using the method getSession().getAttribute()). This is where the problem is: the twitter object is always null!
plz sort it out

Origin http://127.0.0.1:8888 is not allowed by Access-Control-Allow-Origin

I got this problem while trying to access REST web service using GWT client.
I inspect the chrome page then i got the following error from console
XMLHttpRequest cannot load http://localhost:8080/RestWeb/webresources/generic/get. Origin http://127.0.0.1:8888 is not allowed by Access-Control-Allow-Origin.
Following is my client side code
public void onModuleLoad() {
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
"http://localhost:8080/RestWeb/webresources/generic/get");
builder.setCallback(new RequestCallback() {
#Override
public void onResponseReceived(Request request, Response response) {
Window.alert("onResponseReceived");
}
#Override
public void onError(Request request, Throwable exception) {
}
});
builder.setHeader("Content-Type",
"text/plain,application/json,text/xml");
builder.setHeader("Access-Control-Allow-Methods",
"PUT, GET, POST, DELETE, OPTIONS");
builder.setHeader("Access-Control-Allow-Headers", "Content-Type");
builder.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:8888");
try {
builder.send();
} catch (RequestException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
My server side code is :
#Path("generic")
#WebService
public class GenericResource {
#Context
private UriInfo context;
#Context
private HttpServletResponse response;
private String content = "content";
/**
* Creates a new instance of GenericResource
*/
public GenericResource() {
}
#GET
#Path("/get")
#Produces("application/json,text/plain")
public String getXml() {
System.out.println("GET");
//response.addHeader(content, content);
return this.content + " from get method";
}
}
I tried in different ways to get answer. Please help me.
You need to change your server code to support CORS.
One option is a filter:
public class CorsFilter extends OncePerRequestFilter {
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) {
// CORS "pre-flight" request
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
response.addHeader("Access-Control-Allow-Headers", "Content-Type");
response.addHeader("Access-Control-Max-Age", "1800");//30 min
}
filterChain.doFilter(request, response);
}
}
The web.xml needs adding the following too:
<filter>
<filter-name>cors</filter-name>
<filter-class>com.xxx.CorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cors</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Since it's an old question, if one is facing similar issues today - he or she may want to consider using a nice "CORS Filter" that handles all CORS stuff for you in a completely transparent way. Here's the link

Tapestry, request processing from another application

i'have two web appli, tapestry appli and a simple web appli(servelt). in tapestry appli , i have a form, and when it'll be sent, i call a httpClient for sending some informations to author appli using apache's httpClient. like this
void onSubmitFromForm() {
try {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://localhost:8080/appli2/recep");
post.setHeader("referer", "http://localhost:9090/app1/start");
List<NameValuePair> param = new ArrayList<NameValuePair>();
param.add(new BasicNameValuePair("_data", getData());
post.setEntity(new UrlEncodedFormEntity(param));
HttpResponse response = client.execute(post);
response ?????
} catch (Exception e) {
e.printStackTrace();
}
}
And in my servelt recep of the simple web appli(2) i do the same like below
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
try {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(request.getHeader("referer"));
post.setHeader("p",getP());
client.execute(post);
} catch (Exception e) {
e.printStackTrace();
}
}
So, my recep reviev data from my form but it'cannot response it, i'would that tapersty appli could recieve the param 'P' from the simple web appli ?
thanks
If I'm correct you want your tapestry application to POST some form data received from a form submit within Tapestry to a servlet running on another application.
If this is what you want then what is missing is the haneling of the request and constructing a response in your servlet. Because both your tapestry page and your servlet are POST'ing meaning neither constructs a response for your HttpClient to deal with.
In your servlet you could:
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
response.setContentType("text/plain");
PrintWriter out = response.getWriter();
out.println(getP());
out.close();
}
And deal with the response in your tapesty form handler.

"Access-Control-Allow-Origin:*" has no influence in REST Web Service

I make an AJAX call from JavaScript client (running on machine A) to Web server (running on machine B).
Client tries to access a URL exposed by RESTful Web service (Jersey), and it is blocked with error:
Origin http://localhost/ is not
allowed by
Access-Control-Allow-Origin
In server I added 2 header parameters that allow access to any client. However it didn't help:
#Context
private HttpServletResponse servlerResponse;
#POST
#Path("testme")
public void test(){
servlerResponse.addHeader("Access-Control-Allow-Origin", "*");
servlerResponse.addHeader("Access-Control-Allow-Credentials", "true");
}
The same headers work in case of JSP:
<%
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Credentials", "true");
%>
<html>
<head><title>test jsp</title></head>
<body>
test
</body>
</html>
Am I missing something?
thanks
P.S the client part is:
$.ajax({
type: "POST",
url: "http://localhost:8080/login/testme",
dataType: 'json',
success: onLoginSuccess,
error: onLoginError
});
As a solution, we implemented javax.servlet.Filter that adds required headers to every response:
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, java.io.IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
// This should be added in response to both the preflight and the actual request
response.addHeader("Access-Control-Allow-Origin", "*");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.addHeader("Access-Control-Allow-Credentials", "true");
}
chain.doFilter(req, resp);
}
#epeleg This is my preferred way of doing things like this is to do filtering of response (Jersey 2.x):
#Provider
public class CORSFilter implements ContainerResponseFilter {
#Override
public void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) throws IOException {
responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
}
}