| home | Javazoid |
| source code |
HttpProxy revisitedLast year, I wrote a simple proxy server that was designed to understand the flow of traffic between a JDBC driver and a SQL server database. This year's proxy is an Http version that I devised to understand traffic -- particularly POST data -- between a browser and a web server. It is also a much more fully functional server that shuttles both character and binary data between client and server. During the transactions, some of the data captured in these streams are captured and directed to System.out for the purpose of debugging. HttpProxy is set up like a 4 part transaction : client "stream in" feeds a target server "stream out"; when traffic is returned from the target server's input stream, it is passed out to the client's output stream. The only real fly in the ointment is to understand that the browser client creates a socket that essentially blocks until its output stream receives data. Therefore, the Proxy server reader to this stream must know when to exit the "read" loop. I think most implementations require the Proxy client "stream in" reader to read lines until one line comes up zero-length. Since this proxy is implemented as a byte stream reaser (rather than character) it would be necessary to inspect the bytes, convert them to characters and look for a sequence of "\r, \n, \r, \n". At that point, the Http GET or POST request is complete and the Proxy passes it along to the target server. For this implementation, I did not create a readLine method (which isn't available for byte streams.) Rather I waited until the buffer came back less than full, which works reasonably when the buffer is 1kb or larger. The returned data from the target is much easier to handle. The Proxy reads until there is nothing left (a null is read from the stream) and it passes everything along to the client. The Proxy as coded allows a developer to code for anything of interest. Read the request steam, analyze the contents of the response, capture post data, debug a multi-part (usually a file upload) stream. I have even used it to study some disturbing differences between an Internet Explorer 5.5 request and the same (or so I thought) request from IE 6.0 Unfortunately, though, this is an HTTP proxy and to get it to fully work between a JDBC driver and its database or between RMI client and server, code has to be modified. This HTTP proxy assumes that the HTTP request is encoded with "latin1" strings, which can lead to mysterious output from a JDBC driver or other source. Each request source also defines its own request delimiter behaviour. You need to tinker with the JDBC driver to understand where its request terminates. If you can't do that, you won't have a proper request to pass to the target server. Wish listOf course, a Proxy that you have to code for every variety of access is a clumsy tool. While the source code is less than 100 lines, it would be a great feature to allow developers and potentially non-developer users the ability to script their own access to the Proxy. For example, the ability to embed Python code from the Java System.in would be cool. Maybe next time... ResourcesI have a well worn copy of "Java Network Programming" by Merlin Hughes, Michael Shoffner and Derek Hammer. You can view some sample chapters here. There are a couple of more fully functional Java proxy servers out there. You can look at one from Steve Hseuh or another from Kirill Kouzoubov Copyright (c) Gervase Gallant 2003. |