HTTP Trace Applet

This applet uses the generic java.net.Socket class to connect to its origin server (or other remote hosts), send a HTTP request, and print out the web server's response.  It requires IE 4.0, Communicator 4.0 or HotJava 1.1.  The source code of this applet is listed below and is also included in the HttpTrace.jar file for this page.  This applet is digitally signed so that it can connect to any desired hosts.


Click on the "Send" button to send the HTTP request.  You may enter any valid URL in the first text box.  The "http://" prefix can be omitted. If your machine cannot resolve internet addresses, you must enter the numeric IP address of the web server, e.g. 64.82.109.234 instead of www.idssoftware.com.

Note: If you came from the article Firewall Access in Java Applets, the most relavent code is the very last method setNavigatorProxyProperties().   This method is called once in the run() method to enable Communicator's Java VM to use the browser's SOCKS proxy setting for java.net.Socket connections.   Please use the "Back" button in your browser to return to the article.


/*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
* PARTICULAR PURPOSE.
*
* Copyright (c) 1998-2005  IDS Software.  All Rights Reserved.
*
*  Module:  HttpTrace.java
*
*  Comment: Send a HTTP request and print out the response 
*		    from the Web server.
*
*  Changes:
*
*  01-28-05  Changed "Connection:" header to "User-Agent:", and 
*            changed "\n" to "\r\n" to comply with HTTP standard.
*  10-26-00  Remove POST method and change Headers drop down box
*            to "Proxy Server" so it can trace proxy response.
*  01-06-99  Added support for Netscape for Unix which uses file
*            name "preferences.js" instead of "prefs.js"
*/
import java.applet.*;
import java.awt.*;
import java.net.*;
import java.io.*;
import java.util.*;
import netscape.security.PrivilegeManager;

public class HttpTrace extends Applet implements Runnable
{
	java.awt.Label label1;
	java.awt.TextField where;
	java.awt.Button sendBttn;
	java.awt.Label label2;
	java.awt.Choice method;
	java.awt.TextArea textWin;
	java.awt.TextField status;
	java.awt.Label label3;
	java.awt.Button clearBttn;
	java.awt.Label label4;
	java.awt.TextField proxy;

	public void init()
	{
		setLayout(null);
		resize(432,302);
		label1 = new java.awt.Label("URL: ");
		label1.reshape(12,12,36,19);
		add(label1);
		where = new java.awt.TextField();
		where.reshape(48,12,324,20);
		add(where);
		sendBttn = new java.awt.Button();
		sendBttn.setLabel("Send");
		sendBttn.reshape(372,12,48,20);
		add(sendBttn);
		label2 = new java.awt.Label("Method: ");
		label2.reshape(12,37,48,19);
		add(label2);
		method = new java.awt.Choice();
		method.addItem("HEAD ");
		method.addItem("GET ");
		add(method);
		method.reshape(60,37,60,20);
		textWin = new java.awt.TextArea();
		textWin.reshape(12,64,408,206);
		textWin.setFont(new Font("Courier", Font.PLAIN, 12));
		add(textWin);
		status = new java.awt.TextField();
		status.reshape(56,276,316,20);
		add(status);
		label3 = new java.awt.Label("Status: ");
		label3.reshape(12,276,44,19);
		add(label3);
		clearBttn = new java.awt.Button();
		clearBttn.setLabel("Clear");
		clearBttn.reshape(372,276,48,20);
		add(clearBttn);
		label4 = new java.awt.Label("Proxy Server: ",Label.RIGHT);
		label4.reshape(120,37,80,19);
		add(label4);
		proxy = new java.awt.TextField();
		add(proxy);
		proxy.reshape(200,37,218,20);

		String os = System.getProperty("os.name");
		if (os.equals("SunOS")) {
			label1.reshape(12,12,36,28);
			where.reshape(48,12,324,28);
			sendBttn.reshape(372,12,48,28);
			label2.reshape(12,40,48,28);
			method.reshape(72,40,60,28);
			textWin.reshape(12,69,408,206);
			status.reshape(56,276,316,28);
			label3.reshape(12,276,44,28);
			clearBttn.reshape(372,276,48,28);
			label4.reshape(144,40,60,28);
			proxy.reshape(204,40,216,28);
		}
	}

	private Thread theThread = null;

	public void start() {
		textWin.setText("");
		status.setText("Ready");
		if (theThread == null) {
			theThread = new Thread(this);
			theThread.start();
		}
	}
	public void stop() {
		if ((theThread != null) && theThread.isAlive()) 
			theThread.stop();
		theThread = null;
	}

	public void run()
	{
	  try {
		String s = where.getText();
		if (s.length() == 0) {
			where.setText(getHost());
			setNavigatorProxyProperties();
			return;
		}
		if (!s.startsWith("http://"))
			s = "http://" + s;
		try {
			PrivilegeManager.enablePrivilege("UniversalConnect");
		} catch (Throwable e) {};

		URL url = new URL(s);
		int port = url.getPort(), i;
		if (port < 0) port = 80;
		status.setText("Connecting to host...");
		String prxy = proxy.getText();
		if (prxy.length() == 0) {
			newSocket(url.getHost(), port, 1024);
			s = url.getFile();
		}
		else {
			i = prxy.indexOf(':');
			if (i == -1)
				newSocket(prxy, 80, 1024);
			else
				newSocket(
					prxy.substring(0, i), 
					Integer.parseInt(prxy.substring(i+1)),
					1024);
		}
		status.setText("Sending HTTP request...");
		send(method.getSelectedItem());
		send(s);
		send(" HTTP/1.0\r\nAccept: */*\r\nUser-Agent: Java/1.1\r\n");
		send("Host: " + url.getHost() + ':' + port + "\r\n\r\n");
		status.setText("Flushing output stream...");
		flushOutput();
		println();

		status.setText("Reading response...");
		sock.setSoTimeout(15000);
		int len = -1;
		while ((s = readLn()).length() != 0) {
			println(s);
			s = s.toLowerCase();
			if (s.startsWith("content-length:")) {
				s = s.substring(15).trim();
				len = Integer.parseInt(s);
			}
		}
		println();
		if (len != 0 && method.getSelectedIndex() != 0) {
			i = (len < 0 || len > 2048 ? 2048 : len);
			byte[] buf = new byte[i];
			if (len > 0)
				sin.readFully(buf);
			else
				i = sin.read(buf, 0, i);
			println(new String(buf, 0, i));
			print("\n\n");
		}
		closeSocket();
		status.setText("Ready");
	  }
	  catch (InterruptedIOException e) {
		status.setText("Read timeout expired");
		closeSocket();
	  }
	  catch (Throwable e) {
		status.setText(e.toString());
	  }
	}

	public boolean action(Event event, Object arg) {
		if (event.target == sendBttn) {
			run();
			return true;
		}
		else if (event.target == clearBttn) {
			textWin.setText("");
			status.setText("");
			return true;
		}
		return super.action(event, arg);
	}

	protected Socket	sock;
	protected DataInputStream sin;
	protected BufferedOutputStream sout;

	protected void newSocket(String host, int port, int bufSize)
			throws IOException {
		sock = new Socket(host, port);
		sin  = new DataInputStream(new 
		           BufferedInputStream(sock.getInputStream(), bufSize));
		sout = new BufferedOutputStream(sock.getOutputStream(), bufSize);
	}

	protected void send(String s) throws IOException {
	    print(s);
		sout.write(s.getBytes());
	}

	protected String readLn() throws IOException {
		return sin.readLine().trim();
	}

	protected void flushOutput() throws IOException {
		sout.flush();
	}

	protected void closeSocket() {
		try { sock.close(); } catch (IOException e) {}
	}

	protected String getHost() {
		URL url = getCodeBase();
		int port = url.getPort();
		return url.getHost() + ':' + (port > 0 ? port : 80);
	}

	public void print(String s) {
		textWin.appendText(s);
	}
	public void println(String s) {
		textWin.appendText(s + '\n');
	}
	public void println() {
		textWin.appendText("\n");
	}

	public static void setNavigatorProxyProperties() {
	  try {
		PrivilegeManager.enablePrivilege("Debugger");
		String s = System.getProperty("network.proxy.type");
		if (s != null)
			return;
		/*
		* Search prefs.js for proxy settings
		*/
		s = System.getProperty("user.home");
		int i, j = s.length();
		if (s.charAt(j-1) != File.separatorChar)
			s += File.separator;
		File f = new File(s + "prefs.js");
		if (!f.exists())
			f = new File(s + "preferences.js");
		BufferedReader in = new BufferedReader(new FileReader(f));
		Properties pref = new Properties();
		String name;
		// Read all preferences into pref
		while ((s = in.readLine()) != null) {
			if (s.indexOf("user_pref") < 0)
				continue;
			// Parse user_pref("name", "value");
			//    or user_pref("name", 21);
			i = s.indexOf('"') + 1;
			if (i < 1) continue;
			j = s.indexOf('"', i);
			if (j < 0) continue;
			name = s.substring(i, j);
			//
			i = s.indexOf(',', j) + 1;
			if (i < 1) continue;
			j = s.lastIndexOf(')');
			if (j < i) continue;
			s = s.substring(i, j).trim();
			i = s.length() - 1;
			if (i > 0 && s.charAt(0) == '"' && s.charAt(i) == '"')
				s = s.substring(1, i);
			pref.put(name, s);
		}
		// Get all system properties
		Properties sys = System.getProperties();
		/*
		* network.proxy.type:
		*    null  Direct connection (no proxy)
		*    1     Manual proxy configuration
		*    2     Automatic proxy configuration
		*/
		s = pref.getProperty("network.proxy.type");
		if (s == null) s = "0";
		sys.put("network.proxy.type", s);
		if (s.equals("1")) {
			// Set SOCKS proxy properties
			s = pref.getProperty("network.hosts.socks_server");
			if (s != null) sys.put("socksProxyHost", s);
			s = pref.getProperty("network.hosts.socks_serverport");
			if (s != null) sys.put("socksProxyPort", s);
			// Set HTTP proxy properties
			s = pref.getProperty("network.proxy.http");
			if (s != null) sys.put("http.proxyHost", s);
			s = pref.getProperty("network.proxy.http_port");
			if (s != null) sys.put("http.proxyPort", s);
			// Set HTTPS proxy properties
			s = pref.getProperty("network.proxy.ssl");
			if (s != null) sys.put("https.proxyHost", s);
			s = pref.getProperty("network.proxy.ssl_port");
			if (s != null) sys.put("https.proxyPort", s);
			// Set FTP proxy properties
			s = pref.getProperty("network.proxy.ftp");
			if (s != null) sys.put("ftpProxyHost", s);
			s = pref.getProperty("network.proxy.ftp_port");
			if (s != null) sys.put("ftpProxyPort", s);
		}
		// Make it permanent
		System.setProperties(sys);
	  }
	  catch (Throwable e) {}
	}
}