Java/JSP/JSP Debug
A command-line interface to a Web server
<source lang="java">
/**
- Copyright (c) 2002 by Phil Hanna
- All rights reserved.
- You may study, use, modify, and distribute this
- software for any purpose provided that this
- copyright notice appears in all copies.
- This software is provided without warranty
- either expressed or implied.
- /
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.util.regex.Matcher; import java.util.regex.Pattern; /**
- Mainline for running the Web client
- /
public class MainWebClient {
/**
* Reads command line parameters, creates a new
* WebClient
object, then invokes it.
*/
public static void main(String[] args)
throws IOException
{
// Default values
String host = "localhost";
int port = 80;
// Use values from command line, if specified
for (int i = 0; i < args.length; i++) {
String arg = args[i];
if (arg.equals("-h") || arg.equals("-help")) {
showUsage();
return;
}
else
if (arg.equals("-host") && ++i < args.length)
host = args[i];
else
if (arg.equals("-port") && ++i < args.length)
port = Integer.parseInt(args[i]);
}
// Create and start the Web client
new WebClient(host, port).run();
}
/**
* Displays the calling syntax
*/
private static void showUsage()
{
String[] text = {
"usage: java com.jspcr.debug.webclient.Main"
+ " [-host <hostName>]"
+ " [-port <portNumber>]",
};
for (int i = 0; i < text.length; i++)
System.out.println(text[i]);
}
}
/**
- Copyright (c) 2002 by Phil Hanna
- All rights reserved.
- You may study, use, modify, and distribute this
- software for any purpose provided that this
- copyright notice appears in all copies.
- This software is provided without warranty
- either expressed or implied.
- /
/**
- A command-line interface to a Web server
- /
class WebClient {
// Instance variables private String host; private int port; /** * Creates a new Web client * @param host the HTTP server * @param port the server port number */ public WebClient(String host, int port) { this.host = host; this.port = port; } /** * Runs the Web client * @throws IOException if a socket error occurs */ public void run() throws IOException { int contentLength = 0; // Open a socket to the Web host Socket socket = new Socket(host, port); // Set up to read input from the user // and echo it to Web host BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); PrintWriter out = new PrintWriter(socket.getOutputStream(), true); // The first line is the HTTP request // e.g., "GET /path HTTP/1.0" String line = in.readLine(); out.println(line); // Read and echo any other headers, stopping // when a blank line is encountered. while ((line = in.readLine()) != null) { line = line.trim(); out.println(line); if (line.equals("")) break; // Check for a Content-Length header Pattern p = Pattern.rupile ("^\\s*([^:]+):\\s+(.*\\S)\\s*$"); Matcher m = p.matcher(line); if (m.matches()) { String name = m.group(1); String value = m.group(2); if (name.equalsIgnoreCase("Content-Length")) contentLength = Integer.parseInt(value); } } // If a non-zero content length header was used, // read and echo that many bytes to the Web host. if (contentLength > 0) { for (int i = 0; i < contentLength; i++) out.print((char) in.read()); out.flush(); } // The server is now working on the request. // Read its output and dump to stdout in = new BufferedReader( new InputStreamReader(socket.getInputStream())); out = new PrintWriter(System.out); for (;;) { line = in.readLine(); if (line == null) break; out.println(line); } // Close files in.close(); out.close(); socket.close(); }
}
</source>
HTTP Echo For testing
<source lang="java">
import java.net.Socket; import java.net.ServerSocket; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.BufferedInputStream; public class HTTPEcho {
private static final int BUF_SIZE = 1024; private Socket browserSocket = null; private Socket webServerSocket = null; private ServerSocket browserListenerSocket = null; private OutputStream toWebServer = null; private BufferedInputStream fromWebServer = null; private OutputStream toBrowser = null; private BufferedInputStream fromBrowser = null; private ServerSocket createListenerSocket(int portNum) { ServerSocket socket = null; try { socket = new ServerSocket(portNum); } catch (IOException ioe) { System.out.println(ioe.getMessage()); System.exit(-1); } return socket; } private Socket createClientSocket(String host, int portNum) { Socket socket = null; try { socket = new Socket(host, portNum); toWebServer = socket.getOutputStream(); fromWebServer = new BufferedInputStream(socket.getInputStream()); } catch (IOException ioe) { System.out.println(ioe.getMessage()); System.exit(-1); } return socket; } private Socket accept () { Socket socket = null; try { socket = browserListenerSocket.accept(); toBrowser = socket.getOutputStream(); fromBrowser = new BufferedInputStream(socket.getInputStream()); } catch (IOException e) { System.out.println("Accept failed: " + e.getMessage()); System.exit(-1); } return socket; } private void setBrowserListenerSocket(ServerSocket socket) { browserListenerSocket = socket; } private void setWebServerSocket(Socket socket) { webServerSocket = socket; } private void setBrowserSocket(Socket socket) { browserSocket = socket; } private int readLine(InputStream in, byte[] b, int off, int len) throws IOException { if (len <= 0) { return 0; } int count = 0, c; while ((c = in.read()) != -1 && count < len) { b[off++] = (byte)c; count++; if (c == "\n") { break; } } return count > 0 ? count : -1; } private void echoBuffer(BufferedInputStream in, OutputStream out) { byte[] readBuf = new byte[BUF_SIZE]; try { int rlen = -1; int bodyLen = 0; String line = null; do { line = null; rlen = readLine(in, readBuf, 0, BUF_SIZE); if (rlen > 0) { line = new String(readBuf, 0, rlen); System.out.print(line); if (line.startsWith("Content-Length: ")) { String size = line.substring("Content-Length: ".length(), line.length()); bodyLen = Integer.parseInt(size.trim()); } out.write(readBuf, 0, rlen); } } while ((rlen > 0) && !(line.equals("\r\n"))); if (bodyLen > 0) { System.out.println("<Entity-Body>"); int count = 0; do { rlen = in.read(readBuf, 0, BUF_SIZE); if (rlen > 0) { out.write(readBuf, 0, rlen); count += rlen; }else break; } while (count < bodyLen); } out.flush(); } catch (IOException ioe) { System.out.println(ioe.getMessage()); } finally { readBuf = null; } } private void echo() { System.out.println("\nHTTP REQUEST:"); echoBuffer(fromBrowser, toWebServer); System.out.println("\nHTTP REPLY:"); echoBuffer(fromWebServer, toBrowser); } private void closeClientDescriptors() { try { fromWebServer.close(); toWebServer.close(); webServerSocket.close(); fromBrowser.close(); toBrowser.close(); browserSocket.close(); } catch (IOException ioe) { System.out.println(ioe.getMessage()); } } public static void main(String [] args) { HTTPEcho echo = new HTTPEcho(); if (args.length > 1) { System.out.println("Starting HTTPEcho on port: " + args[0] + ". "); System.out.println("Web server host: " + args[1] + "."); System.out.println("Web server is on port: " + args[2] + "."); int interceptorPort = Integer.parseInt(args[0]); String webServerHost = args[1]; int webServerPort = Integer.parseInt(args[2]); echo.setBrowserListenerSocket(echo.createListenerSocket(interceptorPort)); while (true) { echo.setBrowserSocket(echo.accept()); echo.setWebServerSocket(echo.createClientSocket(webServerHost, webServerPort)); echo.echo(); echo.closeClientDescriptors(); } } else { System.out.println("Usage: java HTTPEcho " + "interceptorPort " + "webServerHost webServerPort"); } }
}
</source>
Mainline for the HTTP tracer tool
<source lang="java">
/**
* Copyright (c) 2002 by Phil Hanna * All rights reserved. * * You may study, use, modify, and distribute this * software for any purpose provided that this * copyright notice appears in all copies. * * This software is provided without warranty * either expressed or implied. */
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.io.Writer; import java.net.ServerSocket; import java.net.Socket; /**
* Mainline for the HTTP tracer tool */
public class MainHTTPTracerTool {
public static void main(String[] args) throws IOException { String opt_host = null; String opt_port = null; String opt_tracerPort = null; String opt_log = null; try { // Parse command line arguments for (int i = 0, n = args.length; i < n; i++) { String arg = args[i]; if (arg.equals("-h")) { showUsage(); return; } if (arg.equals("-host") && (i + 1 < n)) opt_host = args[++i]; else if (arg.equals("-port") && (i + 1 < n)) opt_port = args[++i]; else if (arg.equals("-tracerPort") && (i + 1 < n)) opt_tracerPort = args[++i]; else if (arg.equals("-log") && (i + 1 < n)) opt_log = args[++i]; else throw new IllegalArgumentException("Unrecognized option " + arg); } // Verify that there is no port conflict int testTracerPort = (opt_tracerPort == null) ? Tracer.DEFAULT_PORT : Integer.parseInt(opt_tracerPort); int testHostPort = (opt_port == null) ? RequestHandler.DEFAULT_PORT : Integer.parseInt(opt_port); if (testTracerPort == testHostPort) throw new IllegalArgumentException( "Cannot assign port and tracerPort both to " + testHostPort); } catch (IllegalArgumentException e) { System.err.println(e.getMessage()); return; } // Create the tracer and set its properties Tracer tracer = new Tracer(); if (opt_host != null) tracer.setHost(opt_host); if (opt_port != null) tracer.setPort(Integer.parseInt(opt_port)); if (opt_tracerPort != null) tracer.setTracerPort(Integer.parseInt(opt_tracerPort)); if (opt_log != null) tracer.setLogWriter(new FileWriter(opt_log)); // Start it running tracer.start(); } public static final void showUsage() { String[] text = { "", "usage: java -jar tracer.jar [options]", "", "where options are:", "", "-host <hostName> (default is localhost)", "-port <hostPort> (default is 80)", "-tracerPort <localPort> (default is 8601)", "-log <fileName> (default is stdout)", }; for (int i = 0; i < text.length; i++) System.out.println(text[i]); }
} /**
* Copyright (c) 2002 by Phil Hanna All rights reserved. * * You may study, use, modify, and distribute this software for any purpose * provided that this copyright notice appears in all copies. * * This software is provided without warranty either expressed or implied. */
/**
* Acts as a proxy web server, capturing requests and responses and echoing the * headers to a log stream. */
class Tracer extends Thread implements Logger {
public static final int DEFAULT_PORT = 8601; private String host; private int port; private int tracerPort; private PrintWriter logWriter; public void run() { // Set defaults if not otherwise specified if (tracerPort == 0) tracerPort = DEFAULT_PORT; if (logWriter == null) logWriter = new PrintWriter(System.out); // Start proxy server try { log("M: Opening tracer server on tracerPort " + tracerPort); ServerSocket server = new ServerSocket(tracerPort); // Loop forever while (true) { // Wait for connection log("M: Waiting for connections"); Socket client = server.accept(); log("M: Connection received from " + client); // Dispatch it to a request handler thread RequestHandler rh = new RequestHandler(client); rh.setLogger(this); if (host != null) rh.setHost(host); if (port != 0) rh.setPort(port); rh.start(); } } catch (IOException e) { e.printStackTrace(); } } // =========================================== // Implementation of Logger // =========================================== /** * Writes a message to the log * * @param message * the message */ public synchronized void log(String message) { logWriter.println(message); logWriter.flush(); } // =========================================== // Property setters // =========================================== /** * Sets the host. * * @param host * the host. */ public void setHost(String host) { this.host = host; } /** * Sets the port. * * @param port * the port. */ public void setPort(int port) { this.port = port; } /** * Sets the tracerPort. * * @param tracerPort * the tracerPort. */ public void setTracerPort(int tracerPort) { this.tracerPort = tracerPort; } /** * Sets the logWriter. * * @param logWriter * the logWriter. */ public void setLogWriter(Writer logWriter) throws IOException { this.logWriter = new PrintWriter(logWriter); }
} /**
* Copyright (c) 2002 by Phil Hanna All rights reserved. * * You may study, use, modify, and distribute this software for any purpose * provided that this copyright notice appears in all copies. * * This software is provided without warranty either expressed or implied. */
/**
* A proxy HTTP server that handles a single request */
class RequestHandler extends Thread {
public static final String DEFAULT_HOST = "localhost";
public static final int DEFAULT_PORT = 80;
private Socket client;
private Logger logger;
private String host;
private int port;
// ===========================================
// Constructors
// ===========================================
/**
* Creates a new RequestHandler
for the specified client
*/
public RequestHandler(Socket client) {
this.client = client;
}
// ===========================================
// Instance methods
// ===========================================
/**
* Copies the request from the client to the server and copies the response
* back to the client.
*/
public void run() {
try {
// Open a socket to the web server
if (host == null)
host = DEFAULT_HOST;
if (port <= 0)
port = DEFAULT_PORT;
Socket server = new Socket(host, port);
// Open I/O streams to the client
InputStream cin = new BufferedInputStream(client.getInputStream());
OutputStream cout = new BufferedOutputStream(client
.getOutputStream());
// Open I/O streams to the server
InputStream sin = new BufferedInputStream(server.getInputStream());
OutputStream sout = new BufferedOutputStream(server
.getOutputStream());
// Copy request line and headers from client to server,
// echoing to logger if specified. Stop after the
// first empty line (end of headers)
int contentLength = 0;
StringBuffer sb = new StringBuffer();
for (;;) {
// Read a byte from client
// and copy it to server
int c = cin.read();
sout.write(c);
// Ignore CR at end of line
if (c == "\r")
continue;
// If LF, process the line
if (c == "\n") {
String line = sb.toString();
sb = new StringBuffer();
// Log the line
logger.log("C: " + line);
// If this is an empty line,
// there are no more headers
if (line.length() == 0)
break;
// If it is a content length header,
// save the content length
int p = line.indexOf(":");
if (p != -1) {
String key = line.substring(0, p).trim();
String value = line.substring(p + 1).trim();
if (key.equalsIgnoreCase("content-length"))
contentLength = Integer.parseInt(value);
}
}
// Otherwise, append char to string buffer
else
sb.append((char) c);
}
sout.flush();
// If content length was specified, read input stream
// and copy to server
if (contentLength > 0) {
for (int i = 0; i < contentLength; i++) {
int c = cin.read();
sout.write(c);
}
sout.flush();
}
// Echo the response back to the client
sb = new StringBuffer();
while (true) {
// Read a byte from server
// and copy it to client
int c = sin.read();
cout.write(c);
// Ignore CR at end of line
if (c == "\r")
continue;
// If LF, process the line
if (c == "\n") {
String line = sb.toString();
sb = new StringBuffer();
// Log the line
logger.log("S: " + line);
// If this is an empty line,
// there are no more headers
if (line.length() == 0)
break;
}
// Otherwise, append char to string buffer
else
sb.append((char) c);
}
cout.flush();
// Copy remaining bytes to client
int bytesCopied = 0;
while (true) {
int c = sin.read();
if (c == -1)
break;
cout.write(c);
bytesCopied++;
}
if (bytesCopied > 0)
cout.flush();
// Close streams and sockets
cin.close();
cout.close();
client.close();
sin.close();
sout.close();
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// ===========================================
// Property setters
// ===========================================
/**
* Sets the logger.
*
* @param logger
* the logger.
*/
public void setLogger(Logger logger) {
this.logger = logger;
}
/**
* Sets the host.
*
* @param host
* the host.
*/
public void setHost(String host) {
this.host = host;
}
/**
* Sets the port.
*
* @param port
* the port.
*/
public void setPort(int port) {
this.port = port;
}
} /**
* Copyright (c) 2002 by Phil Hanna All rights reserved. * * You may study, use, modify, and distribute this software for any purpose * provided that this copyright notice appears in all copies. * * This software is provided without warranty either expressed or implied. */
/**
* The set of methods that must be implemented by a class that logs message */
interface Logger {
/** * Logs a message */ public void log(String s);
}
</source>