Have it your way --#-- This is really simple. Go to Burger King's Nutrition Wizard, find the page with Double Whopper with Cheese and all the condiments. Save it to disk. Open the file with a text editor and find the line that contains <form action="nutrition02.asp" method="post" name="form1">.

Edit this to read action="http://localhost:9000". Now, save it and start Bounce.java up on Port 9000: java Bounce 9000
(You will need to have bound the IP address of 127.0.0.1 to localhost in your hosts file for this to work.)

Open the file with Netscape (or IE). You'll be missing all the images, but that's OK. Click on the "Add!" button. Your browser now posts the form's data (including the hidden fields and the JavaScript mappings) to Bounce listening on Port 9000 of your local machine. And Bounce just sends it right back.

POST / HTTP/1.0 Connection: Keep-Alive User-Agent: Mozilla/4.51 [en] (X11; I; Linux 2.2.5-15 i686) Host: localhost:9000 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */* Accept-Encoding: gzip Accept-Language: en Accept-Charset: iso-8859-1,*,utf-8 Content-type: application/x-www-form-urlencoded Content-length: 89 mt=1&dp=1&mi=&si=++&ac=1&so=55&sc=1&li=86&li=84&li=79&li=65&li=55&li=63&li=50&li=44&li=58
The si=++ field indicates two spaces -- + is the urlencoded version of a space. Copy this last line -- your browser's POST string -- into Pete's POST string. Run Pete and see what happens.

You should get a Location: header that includes a long query string.

HTTP/1.1 302 Object moved Server: Microsoft-IIS/4.0 Date: Sat, 30 Oct 1999 23:55:57 GMT Location: nutrition01.asp?mi=0;55;0;1;,86,84,79,65,55,63,50,44,58,;9&mt=1&dp=1 Connection: Keep-Alive Content-Length: 182 Content-Type: text/html Set-Cookie: ASPSESSIONIDGGQQQGFI=PHKBIBMAFPGCDHBEIFLKDKJL; path=/ Cache-control: private Object moved

Object Moved

This object may be found here.

See the fourth line? The server is redirecting your browser (or Pete) to nutrition01.asp on the current path (/nutrition). Load this string (prepending http://www.burgerking.com/nutrition/) into your browser and see what happens. Wham! You got the nutrition info, right?

Recode Pete to perform a GET. (I've broken the url String object onto three lines and used a StringBuffer object to append them, simply to avoid a line too long to display in some browsers.)

public static void main(String[] args) { String host = "www.burgerking.com"; StringBuffer urlBuffer = "/nutrition/nutrition01.asp?"; urlBuffer.append("mt=1&dp=1&mi=&si=++&ac=1&so=55&sc=1"); urlBuffer.append("&li=86&li=84&li=79&li=65&li=55&li=63&li=50&li=44&li=58"); try { Socket socket = new Socket(host, 80); InputStream response = socket.getInputStream(); PrintWriter agent = new PrintWriter(new OutputStreamWriter(socket.getOutputStream())); agent.println("GET " + url.toString() + " HTTP/1.0"); agent.println(); agent.flush();
And now Pete pulls down the same page. Study this a minute. It becomes clear that the Nutrition Wizard accumulates values. Each "entree" selected in the so field gets appended by the JavaScript to the si field, the sc value gets append to ac and so on. To display the calculator's results, it sends you a Location: header with all the parameters stuffed into the query string. (The query string is the part of the URL following the question mark.)

The script will parse the query string using semi-colons and commas as delimiters for the fields (this is an idiosyncracy of this author's script, not a part of the HTTP spec).

What we've found here is a very clever calculator that saves its state in hidden fields and can accumulate a quite lengthy menu of items. Using the knowledge I've supplied in this gadget tutorial, you may well be able to unlock other secrets of the Webmaster's art.