Subscribe

RSS Feed (xml)

Powered By

Skin Design:
Free Blogger Skins

Powered by Blogger

Sunday, December 2, 2007

java code for Mainline for the HTTP tracer tool

/**
* 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 (default is localhost)",
"-port (default is 80)",
"-tracerPort (default is 8601)",
"-log (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);
}

No comments: