The Bank via HTTP Tunneling

RMI server will accept either JRMP method invocations or HTTP posts, whether or not they came from a servlet doing HTTP tunneling on behalf of a client. You can use this fact to your advantage. For example, one of the big limitations of the default implementation of HTTP tunneling is that it assumes the RMI server is running on the same machine as the web server. This assumption is so basic to HTTP tunneling that it even effects the URL being used; a URL of the form http:cgi-binjava-rmi.cgi?forward=[portnumber] doesnt even include a destination server machine. A custom servlet that implements HTTP tunneling is free to forward the request to other machines. The change is simple: the connectToLocalServer method simply needs to replace InetAddress.getLocalHost with a more appropriate server machine. Replacing one line of code can allow messages to be forwarded to different servers running on different machines. The servlet can also look at the data it is forwarding. Instead of simply copying an instance of InputStream into an instance of OutputStream , it can examine the request and log which client requests which operations. Unfortunately, while its easy to change the forwarding mechanism, its hard to change either the client or the server. Itd be nice to be able to use SSL when connecting to the web server. However, in order to do that, you need to use a different socket factory entirely™and implementing HTTP tunneling is a fair amount of work.

22.6 The Bank via HTTP Tunneling

HTTP tunneling is enabled by default in RMI. Using HTTP tunneling doesnt require any code changes on either the client or the server. Instead, all that is required is that a web server be installed and configured. The complete list of steps to accomplish this for the bank example are: 1. Install the web server. I chose to install JavaWebServer because, as far as I can tell, it is the easiest web server to install and configure. 2. Add the servlet to the web server. This boils down to somehow telling the web server that URLs beginning with cgi-binjava-rmi.cgi are mapped to the servlet handling HTTP tunneling in this case, SimplifiedServletHandler . 3. Test to make sure everything works. Testing is sometimes a little tricky. Developers often dont have a firewall readily available in their development environment. To help get around this difficulty, Sun has provided a socket factory class, sun.rmi.transport.proxy.RMIHttpToCGISocket - Factory , which only uses HTTP tunneling when attempting to connect to a server. That is, of the five ways a default socket factory can connect to a server, instances of sun.rmi.transport.proxy.RMIHttpToCGISocketFactory will use only the final two. Namely: 1. It attempts to connect on port 80 of the server machine and send the request to a URL beginning with cgi-binjava-rmi.cgi. The interpretation of this URL is that the request will be forwarded to a program that interprets the HTTP request and forwards it, as an HTTP request, to the appropriate port on the server machine. 2. If that fails, it attempts to connect on port 80 of the firewall machine and send the request to a URL beginning with cgi-binjava-rmi.cgi. The interpretation of this URL is that the request will be forwarded to a program that interprets the HTTP request and forwards it, as an HTTP request, to the appropriate port on the server machine. Hence, to run the bank example using HTTP tunneling, we simply add another line to the application that launches the client: public class BankClient { public static void mainString[] args { try { RMISocketFactory. setSocketFactorynew sun.rmi.transport.proxy. RMIHttpToCGISocketFactory ; } catch IOException ignored {} new BankClientFrame.show ; } } Of course, if you do this, all the remote method calls from a client, including those associated with the naming service and distributed garbage collection, go through the web server as well. This means that in order to use this socket factory, you need one machine running the web server, the naming service, and all of your servers. This is useful for functionality testing, but can skew results if you attempt to scale-test.

22.7 Drawbacks of HTTP Tunneling