/*
* Copyright 2001-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.axis.utils ;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.ResourceBundle;
import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.plaf.basic.BasicButtonListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
/**
* TCP monitor to log http messages and responses, both SOAP and plain HTTP.
* If you want to choose a different Swing look and feel, set the property
* tcpmon.laf to the classname of the new look and feel
* @author Doug Davis (dug@us.ibm.com)
* @author Steve Loughran
*/
public class tcpmon extends JFrame {
private JTabbedPane notebook = null ;
private static final int STATE_COLUMN = 0 ;
private static final int TIME_COLUMN = 1 ;
private static final int INHOST_COLUMN = 2 ;
private static final int OUTHOST_COLUMN = 3 ;
private static final int REQ_COLUMN = 4 ;
private static final String DEFAULT_HOST="127.0.0.1";
private static final int DEFAULT_PORT=8080;
/**
* this is the admin page
*/
class AdminPage extends JPanel {
public JRadioButton listenerButton, proxyButton ;
public JLabel hostLabel, tportLabel;
public NumberField port;
public HostnameField host;
public NumberField tport ;
public JTabbedPane noteb ;
public JCheckBox HTTPProxyBox ;
public HostnameField HTTPProxyHost;
public NumberField HTTPProxyPort ;
public JLabel HTTPProxyHostLabel, HTTPProxyPortLabel ;
public JLabel delayTimeLabel, delayBytesLabel;
public NumberField delayTime, delayBytes;
public JCheckBox delayBox;
public AdminPage( JTabbedPane notebook, String name ) {
JPanel mainPane = null ;
JButton addButton = null ;
this.setLayout( new BorderLayout() );
noteb = notebook ;
GridBagLayout layout = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
mainPane = new JPanel(layout);
c.anchor = GridBagConstraints.WEST ;
c.gridwidth = GridBagConstraints.REMAINDER;
mainPane.add( new JLabel(getMessage("newTCP00", "Create a new TCP/IP Monitor...") + " "), c );
// Add some blank space
mainPane.add( Box.createRigidArea(new Dimension(1, 5)), c );
// The listener info
///////////////////////////////////////////////////////////////////
JPanel tmpPanel = new JPanel(new GridBagLayout());
c.anchor = GridBagConstraints.WEST ;
c.gridwidth = 1 ;
tmpPanel.add( new JLabel(getMessage("listenPort00", "Listen Port #") + " "), c );
c.anchor = GridBagConstraints.WEST ;
c.gridwidth = GridBagConstraints.REMAINDER ;
tmpPanel.add( port = new NumberField(4), c );
mainPane.add( tmpPanel, c );
mainPane.add( Box.createRigidArea(new Dimension(1, 5)), c );
// Group for the radio buttons
ButtonGroup btns = new ButtonGroup();
c.anchor = GridBagConstraints.WEST ;
c.gridwidth = GridBagConstraints.REMAINDER ;
mainPane.add( new JLabel(getMessage("actAs00", "Act as a...") ), c );
// Target Host/Port section
///////////////////////////////////////////////////////////////////
c.anchor = GridBagConstraints.WEST ;
c.gridwidth = GridBagConstraints.REMAINDER ;
final String listener = getMessage("listener00", "Listener");
mainPane.add( listenerButton = new JRadioButton( listener ), c );
btns.add( listenerButton );
listenerButton.setSelected( true );
listenerButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent event) {
if (listener.equals(event.getActionCommand())) {
boolean state = listenerButton.isSelected();
tport.setEnabled( state );
host.setEnabled( state );
hostLabel.setForeground(state ? Color.black : Color.gray);
tportLabel.setForeground(state ? Color.black : Color.gray);
}
}
}
);
c.anchor = GridBagConstraints.WEST ;
c.gridwidth = 1 ;
mainPane.add( Box.createRigidArea(new Dimension(25, 0)) );
mainPane.add( hostLabel = new JLabel(getMessage("targetHostname00", "Target Hostname") + " "), c );
c.anchor = GridBagConstraints.WEST ;
c.gridwidth = GridBagConstraints.REMAINDER ;
host = new HostnameField(30);
mainPane.add( host, c );
host.setText(DEFAULT_HOST);
c.anchor = GridBagConstraints.WEST ;
c.gridwidth = 1 ;
mainPane.add( Box.createRigidArea(new Dimension(25, 0)) );
mainPane.add( tportLabel = new JLabel(getMessage("targetPort00", "Target Port #") + " "), c );
c.anchor = GridBagConstraints.WEST ;
c.gridwidth = GridBagConstraints.REMAINDER ;
tport = new NumberField(4);
mainPane.add( tport, c );
tport.setValue(DEFAULT_PORT);
// Act as proxy section
///////////////////////////////////////////////////////////////////
c.anchor = GridBagConstraints.WEST ;
c.gridwidth = GridBagConstraints.REMAINDER ;
final String proxy = getMessage("proxy00", "Proxy");
mainPane.add( proxyButton = new JRadioButton( proxy ), c);
btns.add( proxyButton );
proxyButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent event) {
if (proxy.equals(event.getActionCommand())) {
boolean state = proxyButton.isSelected();
tport.setEnabled( !state );
host.setEnabled( !state );
hostLabel.setForeground(state ? Color.gray : Color.black);
tportLabel.setForeground(state ? Color.gray : Color.black);
}
}
}
);
// Spacer
/////////////////////////////////////////////////////////////////
c.anchor = GridBagConstraints.WEST ;
c.gridwidth = GridBagConstraints.REMAINDER ;
mainPane.add( Box.createRigidArea(new Dimension(1, 10)), c );
// Options section
///////////////////////////////////////////////////////////////////
JPanel opts = new JPanel(new GridBagLayout());
opts.setBorder( new TitledBorder(getMessage("options00", "Options")) );
c.anchor = GridBagConstraints.WEST ;
c.gridwidth = GridBagConstraints.REMAINDER ;
mainPane.add( opts, c );
// HTTP Proxy Support section
///////////////////////////////////////////////////////////////////
c.anchor = GridBagConstraints.WEST ;
c.gridwidth = GridBagConstraints.REMAINDER ;
final String proxySupport = getMessage("proxySupport00", "HTTP Proxy Support");
opts.add(HTTPProxyBox = new JCheckBox(proxySupport), c);
c.anchor = GridBagConstraints.WEST ;
c.gridwidth = 1 ;
opts.add( HTTPProxyHostLabel = new JLabel(getMessage("hostname00", "Hostname") + " "), c );
HTTPProxyHostLabel.setForeground( Color.gray );
c.anchor = GridBagConstraints.WEST ;
c.gridwidth = GridBagConstraints.REMAINDER ;
opts.add( HTTPProxyHost = new HostnameField(30), c );
HTTPProxyHost.setEnabled( false );
c.anchor = GridBagConstraints.WEST ;
c.gridwidth = 1 ;
opts.add( HTTPProxyPortLabel = new JLabel(getMessage("port00", "Port #") + " "), c );
HTTPProxyPortLabel.setForeground( Color.gray );
c.anchor = GridBagConstraints.WEST ;
c.gridwidth = GridBagConstraints.REMAINDER ;
opts.add( HTTPProxyPort = new NumberField(4), c );
HTTPProxyPort.setEnabled( false );
HTTPProxyBox.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent event) {
if (proxySupport.equals(event.getActionCommand())) {
boolean b = HTTPProxyBox.isSelected();
Color color = b ? Color.black : Color.gray ;
HTTPProxyHost.setEnabled( b );
HTTPProxyPort.setEnabled( b );
HTTPProxyHostLabel.setForeground( color );
HTTPProxyPortLabel.setForeground( color );
}
}
}
);
// Set default proxy values...
String tmp = System.getProperty( "http.proxyHost" );
if ( tmp != null && tmp.equals("") ) {
tmp = null ;
}
HTTPProxyBox.setSelected( tmp != null );
HTTPProxyHost.setEnabled( tmp != null );
HTTPProxyPort.setEnabled( tmp != null );
HTTPProxyHostLabel.setForeground( tmp != null ? Color.black : Color.gray);
HTTPProxyPortLabel.setForeground( tmp != null ? Color.black : Color.gray);
if ( tmp != null ) {
HTTPProxyBox.setSelected( true );
HTTPProxyHost.setText( tmp );
tmp = System.getProperty( "http.proxyPort" );
if ( tmp != null && tmp.equals("") ) {
tmp = null ;
}
if ( tmp == null ) {
tmp = "80" ;
}
HTTPProxyPort.setText( tmp );
}
//add byte delay fields
opts.add(Box.createRigidArea(new Dimension(1, 10)), c);
c.anchor = GridBagConstraints.WEST;
c.gridwidth = GridBagConstraints.REMAINDER;
final String delaySupport = getMessage("delay00", "Simulate Slow Connection");
opts.add(delayBox = new JCheckBox(delaySupport), c);
//bytes per pause
c.anchor = GridBagConstraints.WEST;
c.gridwidth = 1;
delayBytesLabel=new JLabel(getMessage("delay01", "Bytes per Pause"));
opts.add(delayBytesLabel, c);
delayBytesLabel.setForeground(Color.gray);
c.anchor = GridBagConstraints.WEST;
c.gridwidth = GridBagConstraints.REMAINDER;
opts.add(delayBytes = new NumberField(6), c);
delayBytes.setEnabled(false);
//delay interval
c.anchor = GridBagConstraints.WEST;
c.gridwidth = 1;
delayTimeLabel = new JLabel(getMessage("delay02", "Delay in Milliseconds"));
opts.add(delayTimeLabel, c);
delayTimeLabel.setForeground(Color.gray);
c.anchor = GridBagConstraints.WEST;
c.gridwidth = GridBagConstraints.REMAINDER;
opts.add(delayTime = new NumberField(6), c);
delayTime.setEnabled(false);
//enabler callback
delayBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
if (delaySupport.equals(event.getActionCommand())) {
boolean b = delayBox.isSelected();
Color color = b ? Color.black : Color.gray;
delayBytes.setEnabled(b);
delayTime.setEnabled(b);
delayBytesLabel.setForeground(color);
delayTimeLabel.setForeground(color);
}
}
}
);
// Spacer
//////////////////////////////////////////////////////////////////
mainPane.add( Box.createRigidArea(new Dimension(1, 10)), c );
// ADD Button
///////////////////////////////////////////////////////////////////
c.anchor = GridBagConstraints.WEST ;
c.gridwidth = GridBagConstraints.REMAINDER ;
final String add = getMessage("add00", "Add");
mainPane.add( addButton = new JButton( add ), c );
this.add( new JScrollPane( mainPane ), BorderLayout.CENTER );
// addButton.setEnabled( false );
addButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent event) {
if ( add.equals(event.getActionCommand()) ) {
String text ;
Listener l = null ;
int lPort;
lPort=port.getValue(0);
if(lPort==0) {
//no port, button does nothing
return;
}
String tHost = host.getText();
int tPort = 0 ;
tPort=tport.getValue(0);
SlowLinkSimulator slowLink=null;
if(delayBox.isSelected()) {
int bytes= delayBytes.getValue(0);
int time = delayTime.getValue(0);
slowLink=new SlowLinkSimulator(bytes,time);
}
try {
l = new Listener( noteb, null, lPort, tHost, tPort,
proxyButton.isSelected(), slowLink);
} catch (Exception e){
e.printStackTrace();
}
// Pick-up the HTTP Proxy settings
///////////////////////////////////////////////////
text = HTTPProxyHost.getText();
if ( "".equals(text) ) {
text = null ;
}
l.HTTPProxyHost = text ;
text = HTTPProxyPort.getText();
int proxyPort=HTTPProxyPort.getValue(-1);
if(proxyPort!=-1) {
l.HTTPProxyPort = Integer.parseInt(text);
}
//reset the port
port.setText(null);
/* but not, any more, the target port and host
values
host.setText(null);
tport.setText(null);
*/
}
}
}
);
notebook.addTab( name, this );
notebook.repaint();
notebook.setSelectedIndex( notebook.getTabCount() - 1 );
}
}
/**
* wait for incoming connections, spawn a connection thread when
* stuff comes in.
*/
class SocketWaiter extends Thread {
ServerSocket sSocket = null ;
Listener listener ;
int port ;
boolean pleaseStop = false ;
public SocketWaiter(Listener l, int p) {
listener = l ;
port = p ;
start();
}
public void run() {
try {
listener.setLeft( new JLabel(getMessage("wait00", " Waiting for Connection...") ) );
listener.repaint();
sSocket = new ServerSocket( port );
for (; ; ) {
Socket inSocket = sSocket.accept();
if ( pleaseStop ) {
break ;
}
new Connection( listener, inSocket );
inSocket = null ;
}
} catch ( Exception exp ) {
if ( !"socket closed".equals(exp.getMessage()) ) {
JLabel tmp = new JLabel( exp.toString() );
tmp.setForeground( Color.red );
listener.setLeft( tmp );
listener.setRight( new JLabel("") );
listener.stop();
}
}
}
/**
* force a halt by connecting to self and then closing the server socket
*/
public void halt() {
try {
pleaseStop = true ;
new Socket( "127.0.0.1", port );
if ( sSocket != null ) {
sSocket.close();
}
} catch ( Exception e ) {
e.printStackTrace();
}
}
}
/**
* class to simulate slow connections by slowing down the system
*/
static class SlowLinkSimulator {
private int delayBytes;
private int delayTime;
private int currentBytes;
private int totalBytes;
/**
* construct
* @param delayBytes bytes per delay; set to 0 for no delay
* @param delayTime delay time per delay in milliseconds
*/
public SlowLinkSimulator(int delayBytes, int delayTime) {
this.delayBytes = delayBytes;
this.delayTime = delayTime;
}
/**
* construct by copying delay bytes and time, but not current
* count of bytes
* @param that source of data
*/
public SlowLinkSimulator(SlowLinkSimulator that) {
this.delayBytes=that.delayBytes;
this.delayTime=that.delayTime;
}
/**
* how many bytes have gone past?
* @return
*/
public int getTotalBytes() {
return totalBytes;
}
/**
* log #of bytes pumped. Will pause when necessary. This method is not
* synchronized
* @param bytes
*/
public void pump(int bytes) {
totalBytes+=bytes;
if(delayBytes==0) {
//when not delaying, we are just a byte counter
return;
}
currentBytes += bytes;
if(currentBytes>delayBytes) {
//we have overshot. lets find out how far
int delaysize=currentBytes/delayBytes;
long delay=delaysize*(long)delayTime;
//move byte counter down to the remainder of bytes
currentBytes=currentBytes%delayBytes;
//now wait
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
; //ignore the exception
}
}
}
/**
* get the current byte count
* @return
*/
public int getCurrentBytes() {
return currentBytes;
}
/**
* set the current byte count
* @param currentBytes
*/
public void setCurrentBytes(int currentBytes) {
this.currentBytes = currentBytes;
}
}
/**
* this class handles the pumping of data from the incoming socket to the
* outgoing socket
*/
class SocketRR extends Thread {
Socket inSocket = null ;
Socket outSocket = null ;
JTextArea textArea ;
InputStream in = null ;
OutputStream out = null ;
boolean xmlFormat ;
boolean numericEnc ;
volatile boolean done = false ;
TableModel tmodel = null ;
int tableIndex = 0 ;
String type = null;
Connection myConnection = null;
SlowLinkSimulator slowLink;
public SocketRR(Connection c, Socket inputSocket, InputStream inputStream,
Socket outputSocket, OutputStream outputStream,
JTextArea _textArea, boolean format, boolean numeric,
TableModel tModel, int index, final String type, SlowLinkSimulator slowLink) {
inSocket = inputSocket ;
in = inputStream ;
outSocket = outputSocket ;
out = outputStream ;
textArea = _textArea ;
xmlFormat = format ;
numericEnc= numeric ;
tmodel = tModel ;
tableIndex = index ;
this.type = type;
myConnection = c;
this.slowLink= slowLink;
start();
}
public boolean isDone() {
return ( done );
}
public void run() {
try {
byte[] buffer = new byte[4096];
byte[] tmpbuffer = new byte[8192];
String message = null;
int saved = 0 ;
int len ;
int i1, i2 ;
int i ;
int reqSaved = 0 ;
int tabWidth = 3 ;
boolean atMargin = true ;
int thisIndent = -1,
nextIndent = -1,
previousIndent = -1;
//if ( inSocket != null ) inSocket.setSoTimeout( 10 );
//if ( outSocket != null ) outSocket.setSoTimeout( 10 );
if ( tmodel != null ) {
String tmpStr = (String) tmodel.getValueAt(tableIndex,
REQ_COLUMN);
if ( !"".equals(tmpStr) ) {
reqSaved = tmpStr.length();
}
}
a:
for ( ; ; ) {
if ( done ) {
break;
}
//try{
//len = in.available();
//}catch(Exception e){len=0;}
len = buffer.length ;
// Used to be 1, but if we block it doesn't matter
// however 1 will break with some servers, including apache
if ( len == 0 ) {
len = buffer.length;
}
if ( saved + len > buffer.length) {
len = buffer.length - saved ;
}
int len1 = 0;
while ( len1 == 0 ) {
try {
len1 = in.read(buffer, saved, len);
}
catch ( Exception ex ) {
if ( done && saved == 0 ) {
break a;
}
len1 = -1;
break;
}
}
len = len1;
if ( len == -1 && saved == 0 ) {
break ;
}
if ( len == -1) {
done = true;
}
// No matter how we may (or may not) format it, send it
// on unformatted - we don't want to mess with how its
// sent to the other side, just how its displayed
if ( out != null && len > 0 ) {
slowLink.pump(len);
out.write( buffer, saved, len );
}
if ( tmodel != null && reqSaved < 50 ) {
String old = (String) tmodel.getValueAt( tableIndex,
REQ_COLUMN);
old = old + new String(buffer, saved, len);
if ( old.length() > 50 ) {
old = old.substring(0, 50);
}
reqSaved = old.length();
if ( (i = old.indexOf('\n')) > 0 ) {
old = old.substring(0, i - 1);
reqSaved = 50 ;
}
tmodel.setValueAt( old, tableIndex, REQ_COLUMN );
}
if ( xmlFormat ) {
// Do XML Formatting
boolean inXML = false ;
int bufferLen = saved ;
if ( len != -1 ) {
bufferLen += len ;
}
i1 = 0 ;
i2 = 0 ;
saved = 0 ;
for ( ; i1 < bufferLen ; i1++ ) {
// Except when we're at EOF, saved last char
if ( len != -1 && i1 + 1 == bufferLen ) {
saved = 1;
break;
}
thisIndent = -1;
if ( buffer[i1] == '<' && buffer[i1 + 1] != '/' ) {
previousIndent = nextIndent++;
thisIndent = nextIndent;
inXML = true ;
}
if ( buffer[i1] == '<' && buffer[i1 + 1] == '/' ) {
if (previousIndent > nextIndent) {
thisIndent = nextIndent;
}
previousIndent = nextIndent--;
inXML = true ;
}
if ( buffer[i1] == '/' && buffer[i1 + 1] == '>' ) {
previousIndent = nextIndent--;
inXML = true ;
}
if ( thisIndent != -1 ) {
if ( thisIndent > 0 ) {
tmpbuffer[i2++] = (byte) '\n';
}
for ( i = tabWidth * thisIndent; i > 0; i-- ) {
tmpbuffer[i2++] = (byte) ' ';
}
}
atMargin = ( buffer[i1] == '\n' || buffer[i1] == '\r');
if ( !inXML || !atMargin ) {
tmpbuffer[i2++] = buffer[i1];
}
}
message = new String( tmpbuffer, 0, i2, getEncoding() );
if (numericEnc) {
textArea.append( StringUtils.escapeNumericChar(message) );
} else {
textArea.append( StringUtils.unescapeNumericChar(message) );
}
// Shift saved bytes to the beginning
for ( i = 0 ; i < saved ; i++ ) {
buffer[i] = buffer[bufferLen - saved + i];
}
}
else {
message = new String( buffer, 0, len, getEncoding() );
if (numericEnc) {
textArea.append( StringUtils.escapeNumericChar(message) );
} else {
textArea.append( StringUtils.unescapeNumericChar(message) );
}
}
// this.sleep(3); // Let other threads have a chance to run
}
// this.sleep(3); // Let other threads have a chance to run
// halt();
// Only set the 'done' flag if we were reading from a
// Socket - if we were reading from an input stream then
// we'll let the other side control when we're done
// if ( inSocket != null ) done = true ;
}
catch ( Throwable t ) {
t.printStackTrace();
}
finally {
done = true ;
try {
if (out != null) {
out.flush();
if (null != outSocket) {
outSocket.shutdownOutput();
} else {
out.close();
}
out = null;
}
}
catch (Exception e) {
;
}
try {
if (in != null) {
if (inSocket != null) {
inSocket.shutdownInput();
} else {
in.close();
}
in = null;
}
}
catch (Exception e) {
;
}
myConnection.wakeUp();
}
}
private String getEncoding() {
try {
return XMLUtils.getEncoding();
} catch (Throwable t){
return "UTF-8";
}
}
public void halt() {
try {
if ( inSocket != null ) {
inSocket.close();
}
if ( outSocket != null ) {
outSocket.close();
}
inSocket = null ;
outSocket = null ;
if ( in != null ) {
in.close();
}
if ( out != null ) {
out.close();
}
in = null ;
out = null ;
done = true;
}
catch ( Exception e ) {
e.printStackTrace();
}
}
}
/**
* a connection listens to a single current connection
*/
class Connection extends Thread {
Listener listener ;
boolean active ;
String fromHost ;
String time ;
JTextArea inputText = null ;
JScrollPane inputScroll = null ;
JTextArea outputText = null ;
JScrollPane outputScroll = null ;
Socket inSocket = null ;
Socket outSocket = null ;
Thread clientThread = null ;
Thread serverThread = null ;
SocketRR rr1 = null ;
SocketRR rr2 = null ;
InputStream inputStream = null ;
String HTTPProxyHost = null ;
int HTTPProxyPort = 80 ;
private SlowLinkSimulator slowLink;
public Connection(Listener l) {
listener = l ;
HTTPProxyHost = l.HTTPProxyHost ;
HTTPProxyPort = l.HTTPProxyPort ;
slowLink =l.slowLink;
}
public Connection(Listener l, Socket s ) {
this (l);
inSocket = s ;
start();
}
public Connection(Listener l, InputStream in ) {
this (l);
inputStream = in ;
start();
}
public void run() {
try {
active = true ;
HTTPProxyHost = System.getProperty( "http.proxyHost" );
if ( HTTPProxyHost != null && HTTPProxyHost.equals("") ) {
HTTPProxyHost = null ;
}
if ( HTTPProxyHost != null ) {
String tmp = System.getProperty( "http.proxyPort" );
if ( tmp != null && tmp.equals("") ) {
tmp = null ;
}
if ( tmp == null ) {
HTTPProxyPort = 80 ;
} else {
HTTPProxyPort = Integer.parseInt( tmp );
}
}
if ( inSocket != null ) {
fromHost = (inSocket.getInetAddress()).getHostName();
} else {
fromHost = "resend" ;
}
String dateformat=getMessage("dateformat00", "yyyy-MM-dd HH:mm:ss");
DateFormat df = new SimpleDateFormat(dateformat);
time = df.format( new Date() );
int count = listener.connections.size();
listener.tableModel.insertRow(count + 1, new Object[] {
getMessage("active00", "Active"),
time,
fromHost,
listener.hostField.getText(), ""
}
);
listener.connections.add( this );
inputText = new JTextArea( null, null, 20, 80 );
inputScroll = new JScrollPane( inputText );
outputText = new JTextArea( null, null, 20, 80 );
outputScroll = new JScrollPane( outputText );
ListSelectionModel lsm = listener.connectionTable.getSelectionModel();
if ( count == 0 || lsm.getLeadSelectionIndex() == 0 ) {
listener.outPane.setVisible( false );
int divLoc = listener.outPane.getDividerLocation();
listener.setLeft( inputScroll );
listener.setRight( outputScroll );
listener.removeButton.setEnabled(false);
listener.removeAllButton.setEnabled(true);
listener.saveButton.setEnabled(true);
listener.resendButton.setEnabled(true);
listener.outPane.setDividerLocation(divLoc);
listener.outPane.setVisible( true );
}
String targetHost = listener.hostField.getText();
int targetPort = Integer.parseInt(listener.tPortField.getText());
int listenPort = Integer.parseInt(listener.portField.getText());
InputStream tmpIn1 = inputStream ;
OutputStream tmpOut1 = null ;
InputStream tmpIn2 = null ;
OutputStream tmpOut2 = null ;
if ( tmpIn1 == null ) {
tmpIn1 = inSocket.getInputStream();
}
if ( inSocket != null ) {
tmpOut1 = inSocket.getOutputStream();
}
String bufferedData = null ;
StringBuffer buf = null ;
int index = listener.connections.indexOf( this );
if (listener.isProxyBox.isSelected() || HTTPProxyHost != null) {
// Check if we're a proxy
byte[] b = new byte[1];
buf = new StringBuffer();
String s ;
for ( ; ; ) {
int len ;
len = tmpIn1.read(b, 0, 1);
if ( len == -1 ) {
break ;
}
s = new String( b );
buf.append( s );
if ( b[0] != '\n' ) {
continue ;
}
break ;
}
bufferedData = buf.toString();
inputText.append( bufferedData );
if ( bufferedData.startsWith( "GET " ) ||
bufferedData.startsWith( "POST " ) ||
bufferedData.startsWith( "PUT " ) ||
bufferedData.startsWith( "DELETE " ) ) {
int start, end ;
URL url ;
start = bufferedData.indexOf( ' ' ) + 1;
while ( bufferedData.charAt(start) == ' ' ) {
start++ ;
}
end = bufferedData.indexOf( ' ', start );
String urlString = bufferedData.substring( start, end );
if ( urlString.charAt(0) == '/' ) {
urlString = urlString.substring(1);
}
if ( listener.isProxyBox.isSelected() ) {
url = new URL( urlString );
targetHost = url.getHost();
targetPort = url.getPort();
if ( targetPort == -1 ) {
targetPort = 80 ;
}
listener.tableModel.setValueAt( targetHost, index + 1,
OUTHOST_COLUMN );
bufferedData = bufferedData.substring( 0, start) +
url.getFile() +
bufferedData.substring( end );
}
else {
url = new URL( "http://" + targetHost + ":" +
targetPort + "/" + urlString );
listener.tableModel.setValueAt( targetHost, index + 1,
OUTHOST_COLUMN );
bufferedData = bufferedData.substring( 0, start) +
url.toExternalForm() +
bufferedData.substring( end );
targetHost = HTTPProxyHost ;
targetPort = HTTPProxyPort ;
}
}
}
else {
//
// Change Host: header to point to correct host
//
byte[] b1 = new byte[1];
buf = new StringBuffer();
String s1;
String lastLine = null ;
for ( ; ; ) {
int len ;
len = tmpIn1.read(b1, 0, 1);
if ( len == -1 ) {
break ;
}
s1 = new String( b1 );
buf.append( s1 );
if ( b1[0] != '\n' ) {
continue ;
}
// we have a complete line
String line = buf.toString();
buf.setLength(0);
// check to see if we have found Host: header
if (line.startsWith("Host: ")) {
// we need to update the hostname to target host
String newHost = "Host: " + targetHost + ":" + listenPort + "\r\n";
bufferedData = bufferedData.concat(newHost);
break ;
}
// add it to our headers so far
if (bufferedData == null) {
bufferedData = line;
} else {
bufferedData = bufferedData.concat(line);
}
// failsafe
if (line.equals("\r\n")) {
break;
}
if ("\n".equals(lastLine) && line.equals("\n")) {
break ;
}
lastLine = line ;
}
if ( bufferedData != null ) {
inputText.append( bufferedData );
int idx = bufferedData.length() < 50 ? bufferedData.length() : 50;
s1 = bufferedData.substring( 0, idx );
int i = s1.indexOf('\n');
if ( i > 0 ) {
s1 = s1.substring(0, i - 1);
}
s1 = s1 + " " +
" ";
s1 = s1.substring(0, 51);
listener.tableModel.setValueAt( s1, index + 1,
REQ_COLUMN );
}
}
if ( targetPort == -1 ) {
targetPort = 80 ;
}
outSocket = new Socket(targetHost, targetPort );
tmpIn2 = outSocket.getInputStream();
tmpOut2 = outSocket.getOutputStream();
if ( bufferedData != null ) {
byte[] b = bufferedData.getBytes();
tmpOut2.write( b );
slowLink.pump(b.length);
}
boolean format = listener.xmlFormatBox.isSelected();
boolean numeric = listener.numericBox.isSelected();
//this is the channel to the endpoint
rr1 = new SocketRR(this, inSocket, tmpIn1, outSocket,
tmpOut2, inputText, format, numeric,
listener.tableModel, index + 1, "request:", slowLink);
//create the response slow link from the inbound slow link
SlowLinkSimulator responseLink = new SlowLinkSimulator(slowLink);
//this is the channel from the endpoint
rr2 = new SocketRR( this, outSocket, tmpIn2, inSocket,
tmpOut1, outputText, format, numeric,
null, 0, "response:", responseLink);
while ( rr1 != null || rr2 != null ) {
// Only loop as long as the connection to the target
// machine is available - once that's gone we can stop.
// The old way, loop until both are closed, left us
// looping forever since no one closed the 1st one.
// while( !rr2.isDone() )
if (null != rr1 && rr1.isDone()) {
if ( index >= 0 && rr2 != null) {
listener.tableModel.setValueAt(getMessage("resp00", "Resp"),
1 + index, STATE_COLUMN );
}
rr1 = null;
}
if (null != rr2 && rr2.isDone()) {
if ( index >= 0 && rr1 != null ) {
listener.tableModel.setValueAt(getMessage("req00", "Req"),
1 + index, STATE_COLUMN );
}
rr2 = null;
}
// Thread.sleep( 10 );
synchronized ( this) {
this.wait(1000); //Safety just incase we're not told to wake up.
}
}
// System.out.println("Done ");
// rr1.halt();
// rr2.halt();
active = false ;
/*
if ( inSocket != null ) {
inSocket.close();
inSocket = null ;
}
outSocket.close();
outSocket = null ;
*/
if ( index >= 0 ) {
listener.tableModel.setValueAt(getMessage("done00", "Done"),
1 + index, STATE_COLUMN );
}
}
catch ( Exception e ) {
StringWriter st = new StringWriter();
PrintWriter wr = new PrintWriter(st);
int index = listener.connections.indexOf( this );
if ( index >= 0 ) {
listener.tableModel.setValueAt( getMessage("error00", "Error"), 1 + index, STATE_COLUMN );
}
e.printStackTrace(wr);
wr.close();
if(outputText!=null) {
outputText.append( st.toString() );
} else {
//something went wrong before we had the output area
System.out.println(st.toString());
}
halt();
}
}
synchronized void wakeUp() {
this.notifyAll();
}
public void halt() {
try {
if ( rr1 != null ) {
rr1.halt();
}
if ( rr2 != null ) {
rr2.halt();
}
if ( inSocket != null ) {
inSocket.close();
}
inSocket = null ;
if ( outSocket != null ) {
outSocket.close();
}
outSocket = null ;
}
catch ( Exception e ) {
e.printStackTrace();
}
}
public void remove() {
int index = -1;
try {
halt();
index = listener.connections.indexOf( this );
listener.tableModel.removeRow( index + 1 );
listener.connections.remove( index );
}
catch ( Exception e ) {
System.err.println("index:=" + index + this );
e.printStackTrace();
}
}
}
/**
* this is one of the tabbed panels that acts as the actual proxy
*/
class Listener extends JPanel {
public Socket inputSocket = null ;
public Socket outputSocket = null ;
public JTextField portField = null ;
public JTextField hostField = null ;
public JTextField tPortField = null ;
public JCheckBox isProxyBox = null ;
public JButton stopButton = null ;
public JButton removeButton = null ;
public JButton removeAllButton = null ;
public JCheckBox xmlFormatBox = null ;
public JCheckBox numericBox = null ;
public JButton saveButton = null ;
public JButton resendButton = null ;
public JButton switchButton = null ;
public JButton closeButton = null ;
public JTable connectionTable = null ;
public DefaultTableModel tableModel = null ;
public JSplitPane outPane = null ;
public ServerSocket sSocket = null ;
public SocketWaiter sw = null ;
public JPanel leftPanel = null ;
public JPanel rightPanel = null ;
public JTabbedPane notebook = null ;
public String HTTPProxyHost = null ;
public int HTTPProxyPort = 80 ;
public int delayBytes = 0;
public int delayTime = 0;
public SlowLinkSimulator slowLink;
public final Vector connections = new Vector();
/**
* create a listener
* @param _notebook
* @param name
* @param listenPort
* @param host
* @param targetPort
* @param isProxy
* @param slowLink optional reference to a slow connection
*/
public Listener(JTabbedPane _notebook, String name,
int listenPort, String host, int targetPort,
boolean isProxy, SlowLinkSimulator slowLink) {
notebook = _notebook ;
if ( name == null ) {
name = getMessage("port01", "Port") + " " + listenPort ;
}
//set the slow link to the passed down link
if(slowLink!=null) {
this.slowLink=slowLink;
} else {
//or make up a no-op one.
this.slowLink=new SlowLinkSimulator(0,0);
}
this.setLayout( new BorderLayout() );
// 1st component is just a row of labels and 1-line entry fields
/////////////////////////////////////////////////////////////////////
JPanel top = new JPanel();
top.setLayout( new BoxLayout(top, BoxLayout.X_AXIS) );
top.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
final String start = getMessage("start00", "Start");
top.add( stopButton = new JButton( start ) );
top.add( Box.createRigidArea(new Dimension(5, 0)) );
top.add( new JLabel( " " + getMessage("listenPort01", "Listen Port:") + " ", SwingConstants.RIGHT ) );
top.add( portField = new JTextField( "" + listenPort, 4 ) );
top.add( new JLabel( " " + getMessage("host00", "Host:"), SwingConstants.RIGHT ) );
top.add( hostField = new JTextField( host, 30 ) );
top.add( new JLabel( " " + getMessage("port02", "Port:") + " ", SwingConstants.RIGHT ) );
top.add( tPortField = new JTextField( "" + targetPort, 4 ) );
top.add( Box.createRigidArea(new Dimension(5, 0)) );
top.add( isProxyBox = new JCheckBox(getMessage("proxy00", "Proxy")) );
isProxyBox.addChangeListener( new BasicButtonListener(isProxyBox) {
public void stateChanged(ChangeEvent event) {
JCheckBox box = (JCheckBox) event.getSource();
boolean state = box.isSelected();
tPortField.setEnabled( !state );
hostField.setEnabled( !state );
}
}
);
isProxyBox.setSelected(isProxy);
portField.setEditable(false);
portField.setMaximumSize(new Dimension(50, Short.MAX_VALUE) );
hostField.setEditable(false);
hostField.setMaximumSize(new Dimension(85, Short.MAX_VALUE) );
tPortField.setEditable(false);
tPortField.setMaximumSize(new Dimension(50, Short.MAX_VALUE) );
stopButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent event) {
if ( getMessage("stop00", "Stop").equals(event.getActionCommand()) ) {
stop();
}
if ( start.equals(event.getActionCommand()) ) {
start();
}
}
}
);
this.add( top, BorderLayout.NORTH );
// 2nd component is a split pane with a table on the top
// and the request/response text areas on the bottom
/////////////////////////////////////////////////////////////////////
tableModel = new DefaultTableModel(new String[] {
getMessage("state00", "State"),
getMessage("time00", "Time"),
getMessage("requestHost00", "Request Host"),
getMessage("targetHost", "Target Host"),
getMessage("request00", "Request...")
} , 0 );
tableModel.addRow( new Object[] {
"---", getMessage("mostRecent00", "Most Recent"), "---", "---", "---"
}
);
connectionTable = new JTable(1, 2);
connectionTable.setModel( tableModel );
connectionTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
// Reduce the STATE column and increase the REQ column
TableColumn col ;
col = connectionTable.getColumnModel().getColumn(STATE_COLUMN);
col.setMaxWidth( col.getPreferredWidth() / 2 );
col = connectionTable.getColumnModel().getColumn(REQ_COLUMN);
col.setPreferredWidth( col.getPreferredWidth() * 2 );
ListSelectionModel sel = connectionTable.getSelectionModel();
sel.addListSelectionListener( new ListSelectionListener() {
public void valueChanged(ListSelectionEvent event) {
if (event.getValueIsAdjusting()) {
return ;
}
ListSelectionModel m = (ListSelectionModel) event.getSource();
int divLoc = outPane.getDividerLocation();
if (m.isSelectionEmpty()) {
setLeft( new JLabel(" " + getMessage("wait00", "Waiting for Connection...") ) );
setRight( new JLabel("") );
removeButton.setEnabled(false);
removeAllButton.setEnabled(false);
saveButton.setEnabled(false);
resendButton.setEnabled(false);
}
else {
int row = m.getLeadSelectionIndex();
if ( row == 0 ) {
if ( connections.size() == 0 ) {
setLeft(new JLabel(" " + getMessage("wait00", "Waiting for connection...")));
setRight(new JLabel(""));
removeButton.setEnabled(false);
removeAllButton.setEnabled(false);
saveButton.setEnabled(false);
resendButton.setEnabled(false);
}
else {
Connection conn = (Connection) connections.lastElement();
setLeft( conn.inputScroll );
setRight( conn.outputScroll );
removeButton.setEnabled(false);
removeAllButton.setEnabled(true);
saveButton.setEnabled(true);
resendButton.setEnabled(true);
}
}
else {
Connection conn = (Connection) connections.get(row - 1);
setLeft( conn.inputScroll );
setRight( conn.outputScroll );
removeButton.setEnabled(true);
removeAllButton.setEnabled(true);
saveButton.setEnabled(true);
resendButton.setEnabled(true);
}
}
outPane.setDividerLocation(divLoc);
}
}
);
JPanel tablePane = new JPanel();
tablePane.setLayout( new BorderLayout() );
JScrollPane tableScrollPane = new JScrollPane( connectionTable );
tablePane.add( tableScrollPane, BorderLayout.CENTER );
JPanel buttons = new JPanel();
buttons.setLayout( new BoxLayout(buttons, BoxLayout.X_AXIS) );
buttons.setBorder( BorderFactory.createEmptyBorder(5, 5, 5, 5) );
final String removeSelected = getMessage("removeSelected00", "Remove Selected");
buttons.add( removeButton = new JButton(removeSelected) );
buttons.add( Box.createRigidArea(new Dimension(5, 0)) );
final String removeAll = getMessage("removeAll00", "Remove All");
buttons.add( removeAllButton = new JButton(removeAll) );
tablePane.add( buttons, BorderLayout.SOUTH );
removeButton.setEnabled( false );
removeButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent event) {
if ( removeSelected.equals(event.getActionCommand()) ) {
remove();
}
}
}
);
removeAllButton.setEnabled( false );
removeAllButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent event) {
if ( removeAll.equals(event.getActionCommand()) ) {
removeAll();
}
}
}
);
// Add Response Section
/////////////////////////////////////////////////////////////////////
JPanel pane2 = new JPanel();
pane2.setLayout( new BorderLayout() );
leftPanel = new JPanel();
leftPanel.setAlignmentX( Component.LEFT_ALIGNMENT );
leftPanel.setLayout( new BoxLayout(leftPanel, BoxLayout.Y_AXIS) );
leftPanel.add( new JLabel(" " + getMessage("request01", "Request")) );
leftPanel.add( new JLabel(" " + getMessage("wait01", "Waiting for connection") ));
rightPanel = new JPanel();
rightPanel.setLayout( new BoxLayout(rightPanel, BoxLayout.Y_AXIS) );
rightPanel.add( new JLabel(" " + getMessage("response00", "Response")) );
rightPanel.add( new JLabel("") );
outPane = new JSplitPane(0, leftPanel, rightPanel );
outPane.setDividerSize(4);
pane2.add( outPane, BorderLayout.CENTER );
JPanel bottomButtons = new JPanel();
bottomButtons.setLayout( new BoxLayout(bottomButtons, BoxLayout.X_AXIS));
bottomButtons.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
bottomButtons.add( xmlFormatBox = new JCheckBox( getMessage("xmlFormat00", "XML Format") ) );
bottomButtons.add( numericBox = new JCheckBox( getMessage("numericEnc00", "Numeric" ) ) );
bottomButtons.add( Box.createRigidArea(new Dimension(5, 0)) );
final String save = getMessage("save00", "Save");
bottomButtons.add( saveButton = new JButton( save ) );
bottomButtons.add( Box.createRigidArea(new Dimension(5, 0)) );
final String resend = getMessage("resend00", "Resend");
bottomButtons.add( resendButton = new JButton( resend ) );
bottomButtons.add( Box.createRigidArea(new Dimension(5, 0)) );
final String switchStr = getMessage("switch00", "Switch Layout");
bottomButtons.add( switchButton = new JButton( switchStr ) );
bottomButtons.add( Box.createHorizontalGlue() );
final String close = getMessage("close00", "Close");
bottomButtons.add( closeButton = new JButton( close ) );
pane2.add( bottomButtons, BorderLayout.SOUTH );
saveButton.setEnabled( false );
saveButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent event) {
if ( save.equals(event.getActionCommand()) ) {
save();
}
}
}
);
resendButton.setEnabled( false );
resendButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent event) {
if ( resend.equals(event.getActionCommand()) ) {
resend();
}
}
}
);
switchButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent event) {
if (switchStr.equals(event.getActionCommand()) ) {
int v = outPane.getOrientation();
if ( v == 0 ) {
// top/bottom
outPane.setOrientation(1);
}
else {
// left/right
outPane.setOrientation(0);
}
outPane.setDividerLocation(0.5);
}
}
}
);
closeButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent event) {
if (close.equals(event.getActionCommand()) ) {
close();
}
}
}
);
JSplitPane pane1 = new JSplitPane( 0 );
pane1.setDividerSize(4);
pane1.setTopComponent( tablePane );
pane1.setBottomComponent( pane2 );
pane1.setDividerLocation( 150 );
this.add( pane1, BorderLayout.CENTER );
//
////////////////////////////////////////////////////////////////////
sel.setSelectionInterval(0, 0);
outPane.setDividerLocation( 150 );
notebook.addTab( name, this );
start();
}
public void setLeft(Component left) {
leftPanel.removeAll();
leftPanel.add(left);
}
public void setRight(Component right) {
rightPanel.removeAll();
rightPanel.add(right);
}
public void start() {
int port = Integer.parseInt( portField.getText() );
portField.setText( "" + port );
int i = notebook.indexOfComponent( this );
notebook.setTitleAt( i, getMessage("port01", "Port") + " " + port );
int tmp = Integer.parseInt( tPortField.getText() );
tPortField.setText( "" + tmp );
sw = new SocketWaiter( this, port );
stopButton.setText( getMessage("stop00", "Stop") );
portField.setEditable(false);
hostField.setEditable(false);
tPortField.setEditable(false);
isProxyBox.setEnabled(false);
}
public void close() {
stop();
notebook.remove( this );
}
public void stop() {
try {
for ( int i = 0 ; i < connections.size() ; i++ ) {
Connection conn = (Connection) connections.get( i );
conn.halt();
}
sw.halt();
stopButton.setText( getMessage("start00", "Start") );
portField.setEditable(true);
hostField.setEditable(true);
tPortField.setEditable(true);
isProxyBox.setEnabled(true);
}
catch ( Exception e ) {
e.printStackTrace();
}
}
public void remove() {
ListSelectionModel lsm = connectionTable.getSelectionModel();
int bot = lsm.getMinSelectionIndex();
int top = lsm.getMaxSelectionIndex();
for ( int i = top ; i >= bot ; i-- ) {
((Connection) connections.get(i - 1)).remove();
}
if ( bot > connections.size() ) {
bot = connections.size();
}
lsm.setSelectionInterval(bot, bot);
}
public void removeAll() {
ListSelectionModel lsm = connectionTable.getSelectionModel();
lsm.clearSelection();
while ( connections.size() > 0 ) {
((Connection) connections.get(0)).remove();
}
lsm.setSelectionInterval(0, 0);
}
public void save() {
JFileChooser dialog = new JFileChooser( "." );
int rc = dialog.showSaveDialog( this );
if ( rc == JFileChooser.APPROVE_OPTION ) {
try {
File file = dialog.getSelectedFile();
FileOutputStream out = new FileOutputStream( file );
ListSelectionModel lsm = connectionTable.getSelectionModel();
rc = lsm.getLeadSelectionIndex();
int n = 0;
for (Iterator i = connections.iterator();i.hasNext();n++) {
Connection conn = (Connection)i.next();
if (lsm.isSelectedIndex(n + 1) ||
(!(i.hasNext()) && lsm.getLeadSelectionIndex() == 0)) {
rc = Integer.parseInt( portField.getText() );
out.write("\n==============\n".getBytes());
out.write( ((getMessage("listenPort01", "Listen Port:") + " " + rc + "\n" )).getBytes() );
out.write( (getMessage("targetHost01", "Target Host:") + " " + hostField.getText() +
"\n" ).getBytes() );
rc = Integer.parseInt( tPortField.getText() );
out.write( ((getMessage("targetPort01", "Target Port:") + " " + rc + "\n" )).getBytes() );
out.write( (("==== " + getMessage("request01", "Request") + " ====\n" )).getBytes() );
out.write( conn.inputText.getText().getBytes() );
out.write( (("==== " + getMessage("response00", "Response") + " ====\n" )).getBytes() );
out.write( conn.outputText.getText().getBytes() );
out.write("\n==============\n".getBytes());
}
}
out.close();
}
catch ( Exception e ) {
e.printStackTrace();
}
}
}
public void resend() {
int rc ;
try {
ListSelectionModel lsm = connectionTable.getSelectionModel();
rc = lsm.getLeadSelectionIndex();
if ( rc == 0 ) {
rc = connections.size();
}
Connection conn = (Connection) connections.get( rc - 1 );
if ( rc > 0 ) {
lsm.clearSelection();
lsm.setSelectionInterval(0, 0);
}
InputStream in = null ;
String text = conn.inputText.getText();
// Fix Content-Length HTTP headers
if ( text.startsWith("POST ") || text.startsWith("GET ") ) {
// System.err.println("IN CL" );
int pos1, pos2, pos3 ;
String body, headers, headers1, header2 ;
pos3 = text.indexOf( "\n\n" );
if ( pos3 == -1 ) {
pos3 = text.indexOf( "\r\n\r\n" );
if ( pos3 != -1 ) {
pos3 = pos3 + 4 ;
}
}
else {
pos3 += 2 ;
}
headers = text.substring( 0, pos3 );
pos1 = headers.indexOf( "Content-Length:" );
// System.err.println("pos1: " + pos1 );
// System.err.println("pos3: " + pos3 );
if ( pos1 != -1 ) {
int newLen = text.length() - pos3 ;
pos2 = headers.indexOf( "\n", pos1 );
System.err.println("CL: " + newLen );
System.err.println("Hdrs: '" + headers + "'" );
System.err.println("subTEXT: '" +
text.substring(pos3, pos3 + newLen) + "'");
text = headers.substring(0, pos1) +
"Content-Length: " + newLen + "\n" +
headers.substring(pos2 + 1) +
text.substring(pos3) ;
System.err.println("\nTEXT: '" + text + "'" );
}
}
in = new ByteArrayInputStream( text.getBytes() );
new Connection( this, in );
}
catch ( Exception e ) {
e.printStackTrace();
}
}
}
public tcpmon(int listenPort, String targetHost, int targetPort, boolean embedded) {
super ( getMessage("tcpmon00", "TCPMonitor") );
notebook = new JTabbedPane();
this.getContentPane().add( notebook );
new AdminPage( notebook, getMessage("admin00", "Admin") );
if ( listenPort != 0 ) {
Listener l = null ;
if ( targetHost == null ) {
l = new Listener( notebook, null, listenPort,
targetHost, targetPort, true, null);
} else {
l = new Listener( notebook, null, listenPort,
targetHost, targetPort, false, null);
}
notebook.setSelectedIndex( 1 );
l.HTTPProxyHost = System.getProperty( "http.proxyHost" );
if ( l.HTTPProxyHost != null && l.HTTPProxyHost.equals("") ) {
l.HTTPProxyHost = null ;
}
if ( l.HTTPProxyHost != null ) {
String tmp = System.getProperty( "http.proxyPort" );
if ( tmp != null && tmp.equals("") ) {
tmp = null ;
}
if ( tmp == null ) {
l.HTTPProxyPort = 80 ;
} else {
l.HTTPProxyPort = Integer.parseInt( tmp );
}
}
}
if(!embedded) {
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
this.pack();
this.setSize( 600, 600 );
this.setVisible( true );
}
public tcpmon(int listenPort, String targetHost, int targetPort) {
this(listenPort, targetHost, targetPort, false);
}
/**
* set up the L&F
*/
private static void setupLookAndFeel(boolean nativeLookAndFeel) throws Exception {
String classname= UIManager.getCrossPlatformLookAndFeelClassName();
if(nativeLookAndFeel) {
classname= UIManager.getSystemLookAndFeelClassName();
}
String lafProperty= System.getProperty("tcpmon.laf", "");
if(lafProperty.length()>0) {
classname=lafProperty;
}
try {
UIManager.setLookAndFeel(classname);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
/**
* this is our main method
* @param args
*/
public static void main(String[] args) {
try {
//switch between swing L&F here
setupLookAndFeel(true);
if ( args.length == 3 ) {
int p1 = Integer.parseInt( args[0] );
int p2 = Integer.parseInt( args[2] );
new tcpmon( p1, args[1], p2 );
}
else if ( args.length == 1 ) {
int p1 = Integer.parseInt( args[0] );
new tcpmon( p1, null, 0 );
}
else if ( args.length != 0 ) {
System.err.println( getMessage("usage00", "Usage:")
+ " tcpmon [listenPort targetHost targetPort]\n");
}
else {
new tcpmon(0, null, 0);
}
}
catch ( Throwable exp ) {
exp.printStackTrace();
}
}
// Message resource bundle.
private static ResourceBundle messages = null;
/**
* Get the message with the given key. There are no arguments for this message.
*/
public static String getMessage(String key, String defaultMsg) {
try {
if (messages == null) {
initializeMessages();
}
return messages.getString(key);
} catch (Throwable t) {
// If there is any problem whatsoever getting the internationalized
// message, return the default.
return defaultMsg;
}
} // getMessage
/**
* Load the resource bundle messages from the properties file. This is ONLY done when it is
* needed. If no messages are printed (for example, only Wsdl2java is being run in non-
* verbose mode) then there is no need to read the properties file.
*/
private static void initializeMessages() {
messages = ResourceBundle.getBundle("org.apache.axis.utils.tcpmon");
} // initializeMessages
/**
* a text field with a restricted set of characters
*/
static class RestrictedTextField extends JTextField {
protected String validText;
public RestrictedTextField(String validText) {
setValidText(validText);
}
public RestrictedTextField(int columns, String validText) {
super(columns);
setValidText(validText);
}
public RestrictedTextField(String text, String validText) {
super(text);
setValidText(validText);
}
public RestrictedTextField(String text, int columns, String validText) {
super(text, columns);
setValidText(validText);
}
private void setValidText(String validText) {
this.validText = validText;
}
/**
* fascinatingly, this method is called in the super() constructor,
* meaning before we are fully initialized. C++ doesnt actually permit
* such a situation, but java clearly does...
* @return a new document
*/
public Document createDefaultModel() {
return new RestrictedDocument();
}
/**
* this class strips out invaid chars
*/
class RestrictedDocument extends PlainDocument {
/**
* Constructs a plain text document. A default model using
* <code>GapContent</code> is constructed and set.
*/
public RestrictedDocument() {
}
/**
* add a string; only those chars in the valid text list are allowed
* @param offset
* @param string
* @param attributes
* @throws BadLocationException
*/
public void insertString(int offset, String string, AttributeSet attributes)
throws BadLocationException {
if (string == null) {
return;
}
int len = string.length();
StringBuffer buffer = new StringBuffer(string.length());
for (int i = 0; i < len; i++) {
char ch = string.charAt(i);
if (validText.indexOf(ch) >= 0) {
buffer.append(ch);
}
}
super.insertString(offset, new String(buffer), attributes);
}
} //end class NumericDocument
}
/**
* because we cant use Java1.4's JFormattedTextField, here is
* a class that accepts numbers only
*/
static class NumberField extends RestrictedTextField {
private static final String VALID_TEXT = "0123456789";
/**
* Constructs a new <code>TextField</code>. A default model is created,
* the initial string is <code>null</code>,
* and the number of columns is set to 0.
*/
public NumberField() {
super(VALID_TEXT);
}
/**
* Constructs a new empty <code>TextField</code> with the specified
* number of columns.
* A default model is created and the initial string is set to
* <code>null</code>.
*
* @param columns the number of columns to use to calculate
* the preferred width; if columns is set to zero, the
* preferred width will be whatever naturally results from
* the component implementation
*/
public NumberField(int columns) {
super(columns, VALID_TEXT);
}
/**
* get the int value of a field, any invalid (non int) field returns
* the default
* @param def default value
* @return the field contents
*/
public int getValue(int def) {
int result = def;
String text = getText();
if (text != null && text.length() != 0) {
try {
result = Integer.parseInt(text);
} catch (NumberFormatException e) {
}
}
return result;
}
/**
* set the text to a numeric value
* @param value number to assign
*/
public void setValue(int value) {
setText(Integer.toString(value));
}
} //end class NumericTextField
/**
* hostname fields
*/
static class HostnameField extends RestrictedTextField {
//list of valid chars in a hostname
private static final String VALID_TEXT =
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWZYZ-.";
public HostnameField(int columns) {
super(columns, VALID_TEXT);
}
public HostnameField() {
super(VALID_TEXT);
}
}
}
|