RPC to a different server using Dev Shell

22 views
Skip to first unread message

jfdi

unread,
Jun 30, 2006, 9:33:04 AM6/30/06
to Google Web Toolkit
I had a look to see if anyone else had solved this - I want to use the
Dev shell in conjunction with an app running under tomcat inside
eclipse. The eventual platform will be a single tomcat, but I like the
dev shell too.

I've seen a few posts on this, but no real solutions - so here goes...

My solution to this is to write a dummy servlet which you load into the
dev shell (using the <servlet> bit in gwt.xml - this proxies all the
requests on to the real RPC servlet. Here it is:

package CHANGE.THIS.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class ProxyPassServlet extends HttpServlet {
static final String REAL_URL =
"http://localhost:8085/CHANGE/THISSERVICE";

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse
resp) throws ServletException, IOException {
// open up the real URL

URL url=new URL(REAL_URL);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setDoOutput(true);

// write the incoming headers to the real URL

Enumeration e = req.getHeaderNames();
while(e.hasMoreElements()) {
String a = (String)e.nextElement();
conn.setRequestProperty(a,req.getHeader(a));
}

// write the incoming request

int len;
byte b[] = new byte[1000];

InputStream is = req.getInputStream();
OutputStream os = conn.getOutputStream();

while( (len = is.read(b,0,1000)) > 0 ) {
os.write(b,0,len);
}
is.close();
os.close();

// write the output back to the caller, and we're done!

is = conn.getInputStream();
os = resp.getOutputStream();
while( (len = is.read(b,0,1000)) > 0 ) {
os.write(b,0,len);
}
is.close();
os.close();
}
}

bjorn

unread,
Jun 30, 2006, 6:35:02 PM6/30/06
to Google Web Toolkit
Hi jfdi

We're using the HttpUnit package for our proxy servlet solution. The
WebConversation class,
http://httpunit.sourceforge.net/doc/api/com/meterware/httpunit/WebConversation.html
simulates a web client, from the documentation:

"This class manages cookies used to maintain session context"

Since we're going to have users that are logged in, we depend on a
robust session handling. Would your code also handle sessions? If so, I
would like to switch (and not have to depend on the HttpUnit JAR-files
in the server...)

Thanks for sharing your code,
Björn

For those that need more background on this whole proxying issue, this
page explains the concepts:
http://ajaxpatterns.org/Cross-Domain_Proxy

jfdi

unread,
Jul 1, 2006, 9:42:20 AM7/1/06
to Google Web Toolkit

bjorn wrote:
> Hi jfdi
>
> We're using the HttpUnit package for our proxy servlet solution. The
> WebConversation class,
> http://httpunit.sourceforge.net/doc/api/com/meterware/httpunit/WebConversation.html
> simulates a web client, from the documentation:
>
> "This class manages cookies used to maintain session context"
>
> Since we're going to have users that are logged in, we depend on a
> robust session handling. Would your code also handle sessions? If so, I
> would like to switch (and not have to depend on the HttpUnit JAR-files
> in the server...)

I think all that is needed is to copy the headers back...

String headerKey, headerValue;
int index = 0;

do {
headerKey = conn.getHeaderFieldKey(index);
headerValue = conn.getHeaderField(index);
System.out.println("copying back header:"+headerKey);
if( headerKey != null && headerValue != null ) {
resp.setHeader(headerKey,headerValue);
index++;
}
} while(headerKey != null && headerValue != null);

or something like that. I don't see any cookies going too and fro
though! but I don't think the GWT RPC uses them - if you're pulling XML
docs back, YMMV.

I'd be interested to see how you are managing sessions - I was thinking
about generating my own session token & passing it in/out with the RPC
calls.

Anyone know if the GWTRPC works over HTTPS OK ?

Paul Strack

unread,
Jul 1, 2006, 2:12:30 PM7/1/06
to Google Web Toolkit
GWT RPC works fine with HTTPS. The GWT RPC uses the some protocol/host
as the page that invokes it, so if you page is HTTPS, so are all the
RPC calls.

jfdi

unread,
Jul 6, 2006, 9:55:15 AM7/6/06
to Google Web Toolkit
OK, got it working properly with sessions - heres the code:

Note that I've ended up rewriting the Path bit in the set-cookie.

You can get at the persisted stuff from the session in the RPC call
using

public String testMethod(String s) {
String thing =
(String)getThreadLocalRequest().getSession().getAttribute("hat");
System.out.println("got:"+thing);
getThreadLocalRequest().getSession().setAttribute("hat",thing+"+fish");
return "fish:"+s;
}

And it appears to work.

Heres the proxy:

package CHANGE.THIS.server;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import java.util.Enumeration;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;


import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class ProxyPassServlet extends HttpServlet {

static final String REAL_URL = "http://HOST:PORT/APP/XXXService";
static final String REWRITE_COOKIE_PATH_FROM = "Path=/APP";
static final String REWRITE_COOKIE_PATH_TO = "";

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse
resp) throws ServletException, IOException {
// open up the real URL

URL url=new URL(REAL_URL);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setDoOutput(true);

// write the incoming headers to the real URL

Enumeration e = req.getHeaderNames();
while(e.hasMoreElements()) {
String a = (String)e.nextElement();

conn.addRequestProperty(a,req.getHeader(a));
System.out.println("adding header:"+a);
}

// write the incoming request

int len;
byte b[] = new byte[1000];

InputStream is = req.getInputStream();
OutputStream os = conn.getOutputStream();

while( (len = is.read(b,0,1000)) > 0 ) {
os.write(b,0,len);
}
is.close();
os.close();

// copy cookies back

is = conn.getInputStream();

Map<String,List<String>> m = conn.getHeaderFields();
if( m == null ) {
System.out.println("m is null");
} else {
for( String key : m.keySet() ) {
if( key != null ) {
List<String> values = m.get(key);
for( String value : values ) {
if( key.equals("Set-Cookie")) {
value=value.replace(REWRITE_COOKIE_PATH_FROM,REWRITE_COOKIE_PATH_TO);
}
System.out.println("copying back header:"+key+"="+value);
resp.addHeader(key,value);


}
}
}
}
// write the output back to the caller, and we're done!

Reply all
Reply to author
Forward
0 new messages