~ubuntu-branches/debian/squeeze/axis/squeeze

« back to all changes in this revision

Viewing changes to src/org/apache/axis/utils/tcpmon.java

  • Committer: Bazaar Package Importer
  • Author(s): Vladimír Lapáček
  • Date: 2006-09-06 22:31:39 UTC
  • Revision ID: james.westby@ubuntu.com-20060906223139-l7m5edxeositeppl
Tags: upstream-1.4
Import upstream version 1.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2001-2004 The Apache Software Foundation.
 
3
 * 
 
4
 * Licensed under the Apache License, Version 2.0 (the "License");
 
5
 * you may not use this file except in compliance with the License.
 
6
 * You may obtain a copy of the License at
 
7
 * 
 
8
 *      http://www.apache.org/licenses/LICENSE-2.0
 
9
 * 
 
10
 * Unless required by applicable law or agreed to in writing, software
 
11
 * distributed under the License is distributed on an "AS IS" BASIS,
 
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
13
 * See the License for the specific language governing permissions and
 
14
 * limitations under the License.
 
15
 */
 
16
package org.apache.axis.utils ;
 
17
 
 
18
 
 
19
import java.awt.BorderLayout;
 
20
import java.awt.Color;
 
21
import java.awt.Component;
 
22
import java.awt.Dimension;
 
23
import java.awt.GridBagConstraints;
 
24
import java.awt.GridBagLayout;
 
25
import java.awt.event.ActionEvent;
 
26
import java.awt.event.ActionListener;
 
27
import java.io.ByteArrayInputStream;
 
28
import java.io.File;
 
29
import java.io.FileOutputStream;
 
30
import java.io.InputStream;
 
31
import java.io.OutputStream;
 
32
import java.io.PrintWriter;
 
33
import java.io.StringWriter;
 
34
import java.net.ServerSocket;
 
35
import java.net.Socket;
 
36
import java.net.URL;
 
37
import java.text.DateFormat;
 
38
import java.text.SimpleDateFormat;
 
39
import java.util.Date;
 
40
import java.util.Iterator;
 
41
import java.util.ResourceBundle;
 
42
import java.util.Vector;
 
43
 
 
44
import javax.swing.BorderFactory;
 
45
import javax.swing.Box;
 
46
import javax.swing.BoxLayout;
 
47
import javax.swing.ButtonGroup;
 
48
import javax.swing.JButton;
 
49
import javax.swing.JCheckBox;
 
50
import javax.swing.JFileChooser;
 
51
import javax.swing.JFrame;
 
52
import javax.swing.JLabel;
 
53
import javax.swing.JPanel;
 
54
import javax.swing.JRadioButton;
 
55
import javax.swing.JScrollPane;
 
56
import javax.swing.JSplitPane;
 
57
import javax.swing.JTabbedPane;
 
58
import javax.swing.JTable;
 
59
import javax.swing.JTextArea;
 
60
import javax.swing.JTextField;
 
61
import javax.swing.ListSelectionModel;
 
62
import javax.swing.SwingConstants;
 
63
import javax.swing.UIManager;
 
64
import javax.swing.UnsupportedLookAndFeelException;
 
65
import javax.swing.border.TitledBorder;
 
66
import javax.swing.event.ChangeEvent;
 
67
import javax.swing.event.ListSelectionEvent;
 
68
import javax.swing.event.ListSelectionListener;
 
69
import javax.swing.plaf.basic.BasicButtonListener;
 
70
import javax.swing.table.DefaultTableModel;
 
71
import javax.swing.table.TableColumn;
 
72
import javax.swing.table.TableModel;
 
73
import javax.swing.text.AttributeSet;
 
74
import javax.swing.text.BadLocationException;
 
75
import javax.swing.text.Document;
 
76
import javax.swing.text.PlainDocument;
 
77
 
 
78
 
 
79
/**
 
80
 * TCP monitor to log http messages and responses, both SOAP and plain HTTP.
 
81
 * If you want to choose a different Swing look and feel, set the property
 
82
 * tcpmon.laf to the classname of the new look and feel
 
83
 * @author Doug Davis (dug@us.ibm.com)
 
84
 * @author Steve Loughran
 
85
 */
 
86
 
 
87
public class tcpmon extends JFrame {
 
88
    private JTabbedPane  notebook = null ;
 
89
 
 
90
    private static final int STATE_COLUMN    = 0 ;
 
91
    private static final int TIME_COLUMN     = 1 ;
 
92
    private static final int INHOST_COLUMN   = 2 ;
 
93
    private static final int OUTHOST_COLUMN  = 3 ;
 
94
    private static final int REQ_COLUMN      = 4 ;
 
95
 
 
96
 
 
97
    private static final String DEFAULT_HOST="127.0.0.1";
 
98
    private static final int    DEFAULT_PORT=8080;
 
99
 
 
100
    /**
 
101
     * this is the admin page
 
102
     */
 
103
    class AdminPage extends JPanel {
 
104
        public JRadioButton  listenerButton, proxyButton ;
 
105
        public JLabel        hostLabel, tportLabel;
 
106
        public NumberField  port;
 
107
        public HostnameField host;
 
108
        public NumberField  tport ;
 
109
        public JTabbedPane   noteb ;
 
110
        public JCheckBox     HTTPProxyBox ;
 
111
        public HostnameField    HTTPProxyHost;
 
112
        public NumberField HTTPProxyPort ;
 
113
        public JLabel        HTTPProxyHostLabel, HTTPProxyPortLabel ;
 
114
        public JLabel        delayTimeLabel, delayBytesLabel;
 
115
        public NumberField delayTime, delayBytes;
 
116
        public JCheckBox     delayBox;
 
117
 
 
118
        public AdminPage( JTabbedPane notebook, String name ) {
 
119
            JPanel     mainPane  = null ;
 
120
            JButton    addButton = null ;
 
121
 
 
122
            this.setLayout( new BorderLayout() );
 
123
            noteb = notebook ;
 
124
 
 
125
            GridBagLayout       layout        = new GridBagLayout();
 
126
            GridBagConstraints  c             = new GridBagConstraints();
 
127
 
 
128
            mainPane = new JPanel(layout);
 
129
 
 
130
            c.anchor    = GridBagConstraints.WEST ;
 
131
            c.gridwidth = GridBagConstraints.REMAINDER;
 
132
            mainPane.add( new JLabel(getMessage("newTCP00", "Create a new TCP/IP Monitor...") + " "), c );
 
133
 
 
134
            // Add some blank space
 
135
            mainPane.add( Box.createRigidArea(new Dimension(1, 5)), c );
 
136
 
 
137
            // The listener info
 
138
            ///////////////////////////////////////////////////////////////////
 
139
            JPanel   tmpPanel = new JPanel(new GridBagLayout());
 
140
 
 
141
            c.anchor    = GridBagConstraints.WEST ;
 
142
            c.gridwidth = 1 ;
 
143
            tmpPanel.add( new JLabel(getMessage("listenPort00", "Listen Port #") + " "), c );
 
144
 
 
145
            c.anchor    = GridBagConstraints.WEST ;
 
146
            c.gridwidth = GridBagConstraints.REMAINDER ;
 
147
            tmpPanel.add( port = new NumberField(4), c );
 
148
 
 
149
            mainPane.add( tmpPanel, c );
 
150
 
 
151
            mainPane.add( Box.createRigidArea(new Dimension(1, 5)), c );
 
152
 
 
153
            // Group for the radio buttons
 
154
            ButtonGroup btns = new ButtonGroup();
 
155
 
 
156
            c.anchor    = GridBagConstraints.WEST ;
 
157
            c.gridwidth = GridBagConstraints.REMAINDER ;
 
158
            mainPane.add( new JLabel(getMessage("actAs00", "Act as a...") ), c );
 
159
 
 
160
            // Target Host/Port section
 
161
            ///////////////////////////////////////////////////////////////////
 
162
            c.anchor    = GridBagConstraints.WEST ;
 
163
            c.gridwidth = GridBagConstraints.REMAINDER ;
 
164
 
 
165
            final String listener = getMessage("listener00", "Listener");
 
166
 
 
167
            mainPane.add( listenerButton  = new JRadioButton( listener ), c );
 
168
            btns.add( listenerButton );
 
169
            listenerButton.setSelected( true );
 
170
 
 
171
            listenerButton.addActionListener( new ActionListener() {
 
172
                    public void actionPerformed(ActionEvent event) {
 
173
                        if (listener.equals(event.getActionCommand())) {
 
174
                            boolean state = listenerButton.isSelected();
 
175
 
 
176
                            tport.setEnabled( state );
 
177
                            host.setEnabled( state );
 
178
                            hostLabel.setForeground(state ? Color.black : Color.gray);
 
179
                            tportLabel.setForeground(state ? Color.black : Color.gray);
 
180
                        }
 
181
                    }
 
182
                }
 
183
            );
 
184
 
 
185
            c.anchor    = GridBagConstraints.WEST ;
 
186
            c.gridwidth = 1 ;
 
187
            mainPane.add( Box.createRigidArea(new Dimension(25, 0)) );
 
188
            mainPane.add( hostLabel = new JLabel(getMessage("targetHostname00", "Target Hostname") + " "), c );
 
189
 
 
190
            c.anchor    = GridBagConstraints.WEST ;
 
191
            c.gridwidth = GridBagConstraints.REMAINDER ;
 
192
            host = new HostnameField(30);
 
193
            mainPane.add( host, c );
 
194
            host.setText(DEFAULT_HOST);
 
195
 
 
196
            c.anchor    = GridBagConstraints.WEST ;
 
197
            c.gridwidth = 1 ;
 
198
            mainPane.add( Box.createRigidArea(new Dimension(25, 0)) );
 
199
            mainPane.add( tportLabel = new JLabel(getMessage("targetPort00", "Target Port #") + " "), c );
 
200
 
 
201
            c.anchor    = GridBagConstraints.WEST ;
 
202
            c.gridwidth = GridBagConstraints.REMAINDER ;
 
203
            tport = new NumberField(4);
 
204
            mainPane.add( tport, c );
 
205
            tport.setValue(DEFAULT_PORT);
 
206
 
 
207
            // Act as proxy section
 
208
            ///////////////////////////////////////////////////////////////////
 
209
            c.anchor    = GridBagConstraints.WEST ;
 
210
            c.gridwidth = GridBagConstraints.REMAINDER ;
 
211
            final String proxy = getMessage("proxy00", "Proxy");
 
212
 
 
213
            mainPane.add( proxyButton = new JRadioButton( proxy ), c);
 
214
            btns.add( proxyButton );
 
215
 
 
216
            proxyButton.addActionListener( new ActionListener() {
 
217
                    public void actionPerformed(ActionEvent event) {
 
218
                        if (proxy.equals(event.getActionCommand())) {
 
219
                            boolean state = proxyButton.isSelected();
 
220
 
 
221
                            tport.setEnabled( !state );
 
222
                            host.setEnabled( !state );
 
223
                            hostLabel.setForeground(state ? Color.gray : Color.black);
 
224
                            tportLabel.setForeground(state ? Color.gray : Color.black);
 
225
                        }
 
226
                    }
 
227
                }
 
228
            );
 
229
 
 
230
            // Spacer
 
231
            /////////////////////////////////////////////////////////////////
 
232
            c.anchor    = GridBagConstraints.WEST ;
 
233
            c.gridwidth = GridBagConstraints.REMAINDER ;
 
234
            mainPane.add( Box.createRigidArea(new Dimension(1, 10)), c );
 
235
 
 
236
            // Options section
 
237
            ///////////////////////////////////////////////////////////////////
 
238
            JPanel       opts = new JPanel(new GridBagLayout());
 
239
 
 
240
            opts.setBorder( new TitledBorder(getMessage("options00", "Options")) );
 
241
            c.anchor    = GridBagConstraints.WEST ;
 
242
            c.gridwidth = GridBagConstraints.REMAINDER ;
 
243
            mainPane.add( opts, c );
 
244
 
 
245
            // HTTP Proxy Support section
 
246
            ///////////////////////////////////////////////////////////////////
 
247
            c.anchor    = GridBagConstraints.WEST ;
 
248
            c.gridwidth = GridBagConstraints.REMAINDER ;
 
249
            final String proxySupport = getMessage("proxySupport00", "HTTP Proxy Support");
 
250
 
 
251
            opts.add(HTTPProxyBox = new JCheckBox(proxySupport), c);
 
252
 
 
253
            c.anchor    = GridBagConstraints.WEST ;
 
254
            c.gridwidth = 1 ;
 
255
            opts.add( HTTPProxyHostLabel = new JLabel(getMessage("hostname00", "Hostname") + " "), c );
 
256
            HTTPProxyHostLabel.setForeground( Color.gray );
 
257
 
 
258
            c.anchor    = GridBagConstraints.WEST ;
 
259
            c.gridwidth = GridBagConstraints.REMAINDER ;
 
260
            opts.add( HTTPProxyHost = new HostnameField(30), c );
 
261
            HTTPProxyHost.setEnabled( false );
 
262
 
 
263
            c.anchor    = GridBagConstraints.WEST ;
 
264
            c.gridwidth = 1 ;
 
265
            opts.add( HTTPProxyPortLabel = new JLabel(getMessage("port00", "Port #") + " "), c );
 
266
            HTTPProxyPortLabel.setForeground( Color.gray );
 
267
 
 
268
            c.anchor    = GridBagConstraints.WEST ;
 
269
            c.gridwidth = GridBagConstraints.REMAINDER ;
 
270
            opts.add( HTTPProxyPort = new NumberField(4), c );
 
271
            HTTPProxyPort.setEnabled( false );
 
272
 
 
273
            HTTPProxyBox.addActionListener( new ActionListener() {
 
274
                    public void actionPerformed(ActionEvent event) {
 
275
                        if (proxySupport.equals(event.getActionCommand())) {
 
276
                            boolean b = HTTPProxyBox.isSelected();
 
277
                            Color   color = b ? Color.black : Color.gray ;
 
278
 
 
279
                            HTTPProxyHost.setEnabled( b );
 
280
                            HTTPProxyPort.setEnabled( b );
 
281
                            HTTPProxyHostLabel.setForeground( color );
 
282
                            HTTPProxyPortLabel.setForeground( color );
 
283
                        }
 
284
                    }
 
285
                }
 
286
            );
 
287
 
 
288
            // Set default proxy values...
 
289
            String tmp = System.getProperty( "http.proxyHost" );
 
290
 
 
291
            if ( tmp != null && tmp.equals("") ) {
 
292
                tmp = null ;
 
293
            }
 
294
 
 
295
            HTTPProxyBox.setSelected( tmp != null );
 
296
            HTTPProxyHost.setEnabled( tmp != null );
 
297
            HTTPProxyPort.setEnabled( tmp != null );
 
298
            HTTPProxyHostLabel.setForeground( tmp != null ? Color.black : Color.gray);
 
299
            HTTPProxyPortLabel.setForeground( tmp != null ? Color.black : Color.gray);
 
300
 
 
301
            if ( tmp != null ) {
 
302
                HTTPProxyBox.setSelected( true );
 
303
                HTTPProxyHost.setText( tmp );
 
304
                tmp = System.getProperty( "http.proxyPort" );
 
305
                if ( tmp != null && tmp.equals("") ) {
 
306
                    tmp = null ;
 
307
                }
 
308
                if ( tmp == null ) {
 
309
                    tmp = "80" ;
 
310
                }
 
311
                HTTPProxyPort.setText( tmp );
 
312
            }
 
313
 
 
314
            //add byte delay fields
 
315
            opts.add(Box.createRigidArea(new Dimension(1, 10)), c);
 
316
            c.anchor = GridBagConstraints.WEST;
 
317
            c.gridwidth = GridBagConstraints.REMAINDER;
 
318
            final String delaySupport = getMessage("delay00", "Simulate Slow Connection");
 
319
            opts.add(delayBox = new JCheckBox(delaySupport), c);
 
320
 
 
321
            //bytes per pause
 
322
            c.anchor = GridBagConstraints.WEST;
 
323
            c.gridwidth = 1;
 
324
            delayBytesLabel=new JLabel(getMessage("delay01",  "Bytes per Pause"));
 
325
            opts.add(delayBytesLabel, c);
 
326
            delayBytesLabel.setForeground(Color.gray);
 
327
            c.anchor = GridBagConstraints.WEST;
 
328
            c.gridwidth = GridBagConstraints.REMAINDER;
 
329
            opts.add(delayBytes = new NumberField(6), c);
 
330
            delayBytes.setEnabled(false);
 
331
 
 
332
            //delay interval
 
333
            c.anchor = GridBagConstraints.WEST;
 
334
            c.gridwidth = 1;
 
335
            delayTimeLabel = new JLabel(getMessage("delay02", "Delay in Milliseconds"));
 
336
            opts.add(delayTimeLabel, c);
 
337
            delayTimeLabel.setForeground(Color.gray);
 
338
            c.anchor = GridBagConstraints.WEST;
 
339
            c.gridwidth = GridBagConstraints.REMAINDER;
 
340
            opts.add(delayTime = new NumberField(6), c);
 
341
            delayTime.setEnabled(false);
 
342
 
 
343
            //enabler callback
 
344
            delayBox.addActionListener(new ActionListener() {
 
345
                public void actionPerformed(ActionEvent event) {
 
346
                    if (delaySupport.equals(event.getActionCommand())) {
 
347
                        boolean b = delayBox.isSelected();
 
348
                        Color color = b ? Color.black : Color.gray;
 
349
 
 
350
                        delayBytes.setEnabled(b);
 
351
                        delayTime.setEnabled(b);
 
352
                        delayBytesLabel.setForeground(color);
 
353
                        delayTimeLabel.setForeground(color);
 
354
                    }
 
355
                }
 
356
            }
 
357
            );
 
358
 
 
359
            // Spacer
 
360
            //////////////////////////////////////////////////////////////////
 
361
            mainPane.add( Box.createRigidArea(new Dimension(1, 10)), c );
 
362
 
 
363
            // ADD Button
 
364
            ///////////////////////////////////////////////////////////////////
 
365
            c.anchor    = GridBagConstraints.WEST ;
 
366
            c.gridwidth = GridBagConstraints.REMAINDER ;
 
367
            final String add = getMessage("add00", "Add");
 
368
 
 
369
            mainPane.add( addButton = new JButton( add ), c );
 
370
 
 
371
 
 
372
            this.add( new JScrollPane( mainPane ), BorderLayout.CENTER );
 
373
 
 
374
            // addButton.setEnabled( false );
 
375
            addButton.addActionListener( new ActionListener() {
 
376
                    public void actionPerformed(ActionEvent event) {
 
377
                        if ( add.equals(event.getActionCommand()) ) {
 
378
                            String   text ;
 
379
                            Listener l = null ;
 
380
                            int      lPort;
 
381
                            lPort=port.getValue(0);
 
382
                            if(lPort==0) {
 
383
                                //no port, button does nothing
 
384
                                return;
 
385
                            }
 
386
                            String   tHost = host.getText();
 
387
                            int      tPort = 0 ;
 
388
                            tPort=tport.getValue(0);
 
389
                            SlowLinkSimulator slowLink=null;
 
390
                            if(delayBox.isSelected()) {
 
391
                                int bytes= delayBytes.getValue(0);
 
392
                                int time = delayTime.getValue(0);
 
393
                                slowLink=new SlowLinkSimulator(bytes,time);
 
394
                            }
 
395
                            try {
 
396
                            l = new Listener( noteb, null, lPort, tHost, tPort,
 
397
                                           proxyButton.isSelected(), slowLink);
 
398
                            } catch (Exception e){
 
399
                                e.printStackTrace();
 
400
                            }
 
401
                            // Pick-up the HTTP Proxy settings
 
402
                            ///////////////////////////////////////////////////
 
403
                            text = HTTPProxyHost.getText();
 
404
                            if ( "".equals(text) ) {
 
405
                                text = null ;
 
406
                            }
 
407
                            l.HTTPProxyHost = text ;
 
408
                            text = HTTPProxyPort.getText();
 
409
                            int proxyPort=HTTPProxyPort.getValue(-1);
 
410
                            if(proxyPort!=-1) {
 
411
                                l.HTTPProxyPort = Integer.parseInt(text);
 
412
                            }
 
413
                            //reset the port
 
414
                            port.setText(null);
 
415
 
 
416
                            /* but not, any more, the target port and host
 
417
                               values
 
418
                            host.setText(null);
 
419
                            tport.setText(null);
 
420
                            */
 
421
                        }
 
422
                    }
 
423
                }
 
424
            );
 
425
 
 
426
            notebook.addTab( name, this );
 
427
            notebook.repaint();
 
428
            notebook.setSelectedIndex( notebook.getTabCount() - 1 );
 
429
        }
 
430
 
 
431
 
 
432
    }
 
433
 
 
434
    /**
 
435
     * wait for incoming connections, spawn a connection thread when
 
436
     * stuff comes in.
 
437
     */
 
438
    class SocketWaiter extends Thread {
 
439
        ServerSocket  sSocket = null ;
 
440
        Listener      listener ;
 
441
        int           port ;
 
442
        boolean       pleaseStop = false ;
 
443
 
 
444
        public SocketWaiter(Listener l, int p) {
 
445
            listener = l ;
 
446
            port = p ;
 
447
            start();
 
448
        }
 
449
 
 
450
        public void run() {
 
451
            try {
 
452
                listener.setLeft( new JLabel(getMessage("wait00", " Waiting for Connection...") ) );
 
453
                listener.repaint();
 
454
                sSocket = new ServerSocket( port );
 
455
                for (; ; ) {
 
456
                    Socket inSocket = sSocket.accept();
 
457
 
 
458
                    if ( pleaseStop ) {
 
459
                        break ;
 
460
                    }
 
461
                    new Connection( listener, inSocket );
 
462
                    inSocket = null ;
 
463
                }
 
464
            } catch ( Exception exp ) {
 
465
                if ( !"socket closed".equals(exp.getMessage()) ) {
 
466
                    JLabel tmp = new JLabel( exp.toString() );
 
467
 
 
468
                    tmp.setForeground( Color.red );
 
469
                    listener.setLeft( tmp );
 
470
                    listener.setRight( new JLabel("") );
 
471
                    listener.stop();
 
472
                }
 
473
            }
 
474
        }
 
475
 
 
476
        /**
 
477
         * force a halt by connecting to self and then closing the server socket
 
478
         */
 
479
        public void halt() {
 
480
            try {
 
481
                pleaseStop = true ;
 
482
                new Socket( "127.0.0.1", port );
 
483
                if ( sSocket != null ) {
 
484
                    sSocket.close();
 
485
                }
 
486
            } catch ( Exception e ) {
 
487
                e.printStackTrace();
 
488
            }
 
489
        }
 
490
    }
 
491
 
 
492
 
 
493
    /**
 
494
     * class to simulate slow connections by slowing down the system
 
495
     */
 
496
    static class SlowLinkSimulator {
 
497
        private int delayBytes;
 
498
        private int delayTime;
 
499
        private int currentBytes;
 
500
        private int totalBytes;
 
501
 
 
502
        /**
 
503
         * construct
 
504
         * @param delayBytes bytes per delay; set to 0 for no delay
 
505
         * @param delayTime delay time per delay in milliseconds
 
506
         */
 
507
        public SlowLinkSimulator(int delayBytes, int delayTime) {
 
508
            this.delayBytes = delayBytes;
 
509
            this.delayTime = delayTime;
 
510
        }
 
511
 
 
512
        /**
 
513
         * construct by copying delay bytes and time, but not current
 
514
         * count of bytes
 
515
         * @param that source of data
 
516
         */
 
517
        public SlowLinkSimulator(SlowLinkSimulator that) {
 
518
            this.delayBytes=that.delayBytes;
 
519
            this.delayTime=that.delayTime;
 
520
        }
 
521
 
 
522
        /**
 
523
         * how many bytes have gone past?
 
524
         * @return
 
525
         */
 
526
        public int getTotalBytes() {
 
527
            return totalBytes;
 
528
        }
 
529
 
 
530
        /**
 
531
         * log #of bytes pumped. Will pause when necessary. This method is not
 
532
         * synchronized
 
533
         * @param bytes
 
534
         */
 
535
        public void pump(int bytes) {
 
536
            totalBytes+=bytes;
 
537
            if(delayBytes==0) {
 
538
                //when not delaying, we are just a byte counter
 
539
                return;
 
540
            }
 
541
            currentBytes += bytes;
 
542
            if(currentBytes>delayBytes) {
 
543
                //we have overshot. lets find out how far
 
544
                int delaysize=currentBytes/delayBytes;
 
545
                long delay=delaysize*(long)delayTime;
 
546
                //move byte counter down to the remainder of bytes
 
547
                currentBytes=currentBytes%delayBytes;
 
548
                //now wait
 
549
                try {
 
550
                    Thread.sleep(delay);
 
551
                } catch (InterruptedException e) {
 
552
                    ; //ignore the exception
 
553
                }
 
554
            }
 
555
        }
 
556
 
 
557
        /**
 
558
         * get the current byte count
 
559
         * @return
 
560
         */
 
561
        public int getCurrentBytes() {
 
562
            return currentBytes;
 
563
        }
 
564
 
 
565
        /**
 
566
         * set the current byte count
 
567
         * @param currentBytes
 
568
         */
 
569
        public void setCurrentBytes(int currentBytes) {
 
570
            this.currentBytes = currentBytes;
 
571
        }
 
572
 
 
573
    }
 
574
 
 
575
    /**
 
576
     * this class handles the pumping of data from the incoming socket to the
 
577
     * outgoing socket
 
578
     */
 
579
    class SocketRR extends Thread {
 
580
        Socket        inSocket  = null ;
 
581
        Socket        outSocket  = null ;
 
582
        JTextArea     textArea ;
 
583
        InputStream   in = null ;
 
584
        OutputStream  out = null ;
 
585
        boolean       xmlFormat ;
 
586
        boolean       numericEnc ;
 
587
        volatile boolean       done = false ;
 
588
        TableModel    tmodel = null ;
 
589
        int           tableIndex = 0 ;
 
590
        String type = null;
 
591
        Connection    myConnection = null;
 
592
        SlowLinkSimulator slowLink;
 
593
 
 
594
        public SocketRR(Connection c, Socket inputSocket, InputStream inputStream,
 
595
            Socket outputSocket, OutputStream outputStream,
 
596
            JTextArea _textArea, boolean format, boolean numeric,
 
597
            TableModel tModel, int index, final String type, SlowLinkSimulator slowLink) {
 
598
            inSocket = inputSocket ;
 
599
            in       = inputStream ;
 
600
            outSocket = outputSocket ;
 
601
            out       = outputStream ;
 
602
            textArea  = _textArea ;
 
603
            xmlFormat = format ;
 
604
            numericEnc= numeric ;
 
605
            tmodel    = tModel ;
 
606
            tableIndex = index ;
 
607
            this.type = type;
 
608
            myConnection = c;
 
609
            this.slowLink= slowLink;
 
610
            start();
 
611
        }
 
612
 
 
613
        public boolean isDone() {
 
614
            return ( done );
 
615
        }
 
616
 
 
617
        public void run() {
 
618
            try {
 
619
                byte[]      buffer = new byte[4096];
 
620
                byte[]      tmpbuffer = new byte[8192];
 
621
                String      message = null;
 
622
                int         saved = 0 ;
 
623
                int         len ;
 
624
                int         i1, i2 ;
 
625
                int         i ;
 
626
                int         reqSaved = 0 ;
 
627
                int         tabWidth = 3 ;
 
628
                boolean     atMargin = true ;
 
629
                int         thisIndent = -1,
 
630
                    nextIndent = -1,
 
631
                    previousIndent = -1;
 
632
 
 
633
                //if ( inSocket  != null ) inSocket.setSoTimeout( 10 );
 
634
                //if ( outSocket != null ) outSocket.setSoTimeout( 10 );
 
635
 
 
636
                if ( tmodel != null ) {
 
637
                    String tmpStr = (String) tmodel.getValueAt(tableIndex,
 
638
                            REQ_COLUMN);
 
639
 
 
640
                    if ( !"".equals(tmpStr) ) {
 
641
                        reqSaved = tmpStr.length();
 
642
                    }
 
643
                }
 
644
 
 
645
            a:
 
646
                for ( ; ; ) {
 
647
                    if ( done ) {
 
648
                        break;
 
649
                    }
 
650
                    //try{
 
651
                    //len = in.available();
 
652
                    //}catch(Exception e){len=0;}
 
653
                    len = buffer.length ;
 
654
                    // Used to be 1, but if we block it doesn't matter
 
655
                    // however 1 will break with some servers, including apache
 
656
                    if ( len == 0 ) {
 
657
                        len = buffer.length;
 
658
                    }
 
659
                    if ( saved + len > buffer.length) {
 
660
                        len = buffer.length - saved ;
 
661
                    }
 
662
                    int len1 = 0;
 
663
 
 
664
                    while ( len1 == 0 ) {
 
665
                        try {
 
666
                            len1 = in.read(buffer, saved, len);
 
667
                        }
 
668
                        catch ( Exception ex ) {
 
669
                            if ( done && saved == 0  ) {
 
670
                                break a;
 
671
                            }
 
672
                            len1 = -1;
 
673
                            break;
 
674
                        }
 
675
                    }
 
676
                    len = len1;
 
677
 
 
678
                    if ( len == -1 && saved == 0 ) {
 
679
                        break ;
 
680
                    }
 
681
                    if ( len == -1) {
 
682
                        done = true;
 
683
                    }
 
684
 
 
685
                    // No matter how we may (or may not) format it, send it
 
686
                    // on unformatted - we don't want to mess with how its
 
687
                    // sent to the other side, just how its displayed
 
688
                    if ( out != null && len > 0 ) {
 
689
                        slowLink.pump(len);
 
690
                        out.write( buffer, saved, len );
 
691
                    }
 
692
 
 
693
                    if ( tmodel != null && reqSaved < 50 ) {
 
694
                        String old = (String) tmodel.getValueAt( tableIndex,
 
695
                                REQ_COLUMN);
 
696
 
 
697
                        old = old + new String(buffer, saved, len);
 
698
                        if ( old.length() > 50 ) {
 
699
                            old = old.substring(0, 50);
 
700
                        }
 
701
 
 
702
                        reqSaved = old.length();
 
703
 
 
704
                        if ( (i = old.indexOf('\n')) > 0 ) {
 
705
                            old = old.substring(0, i - 1);
 
706
                            reqSaved = 50 ;
 
707
                        }
 
708
 
 
709
                        tmodel.setValueAt( old, tableIndex, REQ_COLUMN );
 
710
                    }
 
711
 
 
712
                    if ( xmlFormat ) {
 
713
                        // Do XML Formatting
 
714
                        boolean inXML = false ;
 
715
                        int     bufferLen = saved ;
 
716
 
 
717
                        if ( len != -1 ) {
 
718
                            bufferLen += len ;
 
719
                        }
 
720
                        i1 = 0 ;
 
721
                        i2 = 0 ;
 
722
                        saved = 0 ;
 
723
                        for ( ; i1 < bufferLen ; i1++ ) {
 
724
                            // Except when we're at EOF, saved last char
 
725
                            if ( len != -1 && i1 + 1 == bufferLen ) {
 
726
                                saved = 1;
 
727
                                break;
 
728
                            }
 
729
                            thisIndent = -1;
 
730
                            if ( buffer[i1] == '<' && buffer[i1 + 1] != '/' ) {
 
731
                                previousIndent = nextIndent++;
 
732
                                thisIndent = nextIndent;
 
733
                                inXML = true ;
 
734
                            }
 
735
                            if ( buffer[i1] == '<' && buffer[i1 + 1] == '/' ) {
 
736
                                if (previousIndent > nextIndent) {
 
737
                                    thisIndent = nextIndent;
 
738
                                }
 
739
                                previousIndent = nextIndent--;
 
740
                                inXML = true ;
 
741
                            }
 
742
                            if ( buffer[i1] == '/' && buffer[i1 + 1] == '>' ) {
 
743
                                previousIndent = nextIndent--;
 
744
                                inXML = true ;
 
745
                            }
 
746
                            if ( thisIndent != -1 ) {
 
747
                                if ( thisIndent > 0 ) {
 
748
                                    tmpbuffer[i2++] = (byte) '\n';
 
749
                                }
 
750
                                for ( i = tabWidth * thisIndent; i > 0; i-- ) {
 
751
                                    tmpbuffer[i2++] = (byte) ' ';
 
752
                                }
 
753
                            }
 
754
                            atMargin = ( buffer[i1] == '\n' || buffer[i1] == '\r');
 
755
 
 
756
                            if ( !inXML || !atMargin ) {
 
757
                                tmpbuffer[i2++] = buffer[i1];
 
758
                            }
 
759
                        }
 
760
                        message = new String( tmpbuffer, 0, i2, getEncoding() );
 
761
                        if (numericEnc) {
 
762
                            textArea.append( StringUtils.escapeNumericChar(message) );
 
763
                        } else {
 
764
                            textArea.append( StringUtils.unescapeNumericChar(message) );
 
765
                        }
 
766
 
 
767
                        // Shift saved bytes to the beginning
 
768
                        for ( i = 0 ; i < saved ; i++ ) {
 
769
                            buffer[i] = buffer[bufferLen - saved + i];
 
770
                        }
 
771
                    }
 
772
                    else {
 
773
                        message = new String( buffer, 0, len, getEncoding() );
 
774
                        if (numericEnc) {
 
775
                            textArea.append( StringUtils.escapeNumericChar(message) );
 
776
                        } else {
 
777
                            textArea.append( StringUtils.unescapeNumericChar(message) );
 
778
                        }
 
779
                    }
 
780
                // this.sleep(3);  // Let other threads have a chance to run
 
781
                }
 
782
            // this.sleep(3);  // Let other threads have a chance to run
 
783
            // halt();
 
784
            // Only set the 'done' flag if we were reading from a
 
785
            // Socket - if we were reading from an input stream then
 
786
            // we'll let the other side control when we're done
 
787
            //      if ( inSocket != null ) done = true ;
 
788
            }
 
789
            catch ( Throwable t ) {
 
790
                t.printStackTrace();
 
791
            }
 
792
            finally {
 
793
                done = true ;
 
794
                try {
 
795
                    if (out != null) {
 
796
                        out.flush();
 
797
                        if (null != outSocket) {
 
798
                            outSocket.shutdownOutput();
 
799
                        } else {
 
800
                            out.close();
 
801
                        }
 
802
                        out = null;
 
803
                    }
 
804
                }
 
805
                catch (Exception e) {
 
806
                    ;
 
807
                }
 
808
                try {
 
809
                    if (in != null) {
 
810
                        if (inSocket != null) {
 
811
                            inSocket.shutdownInput();
 
812
                        } else {
 
813
                            in.close();
 
814
                        }
 
815
                        in = null;
 
816
                    }
 
817
                }
 
818
                catch (Exception e) {
 
819
                    ;
 
820
                }
 
821
                myConnection.wakeUp();
 
822
            }
 
823
        }
 
824
 
 
825
        private String getEncoding() {
 
826
            try {
 
827
            return XMLUtils.getEncoding();
 
828
 
 
829
            } catch (Throwable t){
 
830
                return "UTF-8";
 
831
            }
 
832
        }
 
833
        
 
834
        public  void halt() {
 
835
            try {
 
836
                if ( inSocket != null ) {
 
837
                    inSocket.close();
 
838
                }
 
839
                if ( outSocket != null ) {
 
840
                    outSocket.close();
 
841
                }
 
842
                inSocket  = null ;
 
843
                outSocket = null ;
 
844
                if ( in != null ) {
 
845
                    in.close();
 
846
                }
 
847
                if ( out != null ) {
 
848
                    out.close();
 
849
                }
 
850
                in = null ;
 
851
                out = null ;
 
852
                done = true;
 
853
            }
 
854
            catch ( Exception e ) {
 
855
                e.printStackTrace();
 
856
            }
 
857
        }
 
858
    }
 
859
 
 
860
 
 
861
    /**
 
862
     * a connection listens to a single current connection
 
863
     */
 
864
    class Connection extends Thread {
 
865
        Listener     listener ;
 
866
        boolean      active ;
 
867
        String       fromHost ;
 
868
        String       time ;
 
869
        JTextArea    inputText    = null ;
 
870
        JScrollPane  inputScroll  = null ;
 
871
        JTextArea    outputText   = null ;
 
872
        JScrollPane  outputScroll = null ;
 
873
        Socket       inSocket     = null ;
 
874
        Socket       outSocket    = null ;
 
875
        Thread       clientThread = null ;
 
876
        Thread       serverThread = null ;
 
877
        SocketRR     rr1          = null ;
 
878
        SocketRR     rr2          = null ;
 
879
        InputStream  inputStream  = null ;
 
880
 
 
881
        String       HTTPProxyHost = null ;
 
882
        int          HTTPProxyPort = 80 ;
 
883
        private SlowLinkSimulator slowLink;
 
884
 
 
885
        public Connection(Listener l) {
 
886
            listener = l ;
 
887
            HTTPProxyHost = l.HTTPProxyHost ;
 
888
            HTTPProxyPort = l.HTTPProxyPort ;
 
889
            slowLink =l.slowLink;
 
890
        }
 
891
 
 
892
        public Connection(Listener l, Socket s ) {
 
893
            this (l);
 
894
            inSocket = s ;
 
895
            start();
 
896
        }
 
897
 
 
898
        public Connection(Listener l, InputStream in ) {
 
899
            this (l);
 
900
            inputStream = in ;
 
901
            start();
 
902
        }
 
903
 
 
904
        public void run() {
 
905
            try {
 
906
                active        = true ;
 
907
 
 
908
                HTTPProxyHost = System.getProperty( "http.proxyHost" );
 
909
                if ( HTTPProxyHost != null && HTTPProxyHost.equals("") ) {
 
910
                    HTTPProxyHost = null ;
 
911
                }
 
912
 
 
913
                if ( HTTPProxyHost != null ) {
 
914
                    String tmp = System.getProperty( "http.proxyPort" );
 
915
 
 
916
                    if ( tmp != null && tmp.equals("") ) {
 
917
                        tmp = null ;
 
918
                    }
 
919
                    if ( tmp == null ) {
 
920
                        HTTPProxyPort = 80 ;
 
921
                    } else {
 
922
                        HTTPProxyPort = Integer.parseInt( tmp );
 
923
                    }
 
924
                }
 
925
 
 
926
                if ( inSocket != null ) {
 
927
                    fromHost = (inSocket.getInetAddress()).getHostName();
 
928
                } else {
 
929
                    fromHost = "resend" ;
 
930
                }
 
931
 
 
932
 
 
933
                String dateformat=getMessage("dateformat00", "yyyy-MM-dd HH:mm:ss");
 
934
                DateFormat   df = new SimpleDateFormat(dateformat);
 
935
 
 
936
                time = df.format( new Date() );
 
937
 
 
938
                int count = listener.connections.size();
 
939
 
 
940
                listener.tableModel.insertRow(count + 1, new Object[] {
 
941
                        getMessage("active00", "Active"),
 
942
                        time,
 
943
                        fromHost,
 
944
                        listener.hostField.getText(), ""
 
945
                    }
 
946
                );
 
947
                listener.connections.add( this );
 
948
                inputText  = new JTextArea( null, null, 20, 80 );
 
949
                inputScroll = new JScrollPane( inputText );
 
950
                outputText = new JTextArea( null, null, 20, 80 );
 
951
                outputScroll = new JScrollPane( outputText );
 
952
 
 
953
                ListSelectionModel lsm = listener.connectionTable.getSelectionModel();
 
954
 
 
955
                if ( count == 0 || lsm.getLeadSelectionIndex() == 0 ) {
 
956
                    listener.outPane.setVisible( false );
 
957
                    int divLoc = listener.outPane.getDividerLocation();
 
958
 
 
959
                    listener.setLeft( inputScroll );
 
960
                    listener.setRight( outputScroll );
 
961
 
 
962
                    listener.removeButton.setEnabled(false);
 
963
                    listener.removeAllButton.setEnabled(true);
 
964
                    listener.saveButton.setEnabled(true);
 
965
                    listener.resendButton.setEnabled(true);
 
966
                    listener.outPane.setDividerLocation(divLoc);
 
967
                    listener.outPane.setVisible( true );
 
968
                }
 
969
 
 
970
                String targetHost = listener.hostField.getText();
 
971
                int    targetPort = Integer.parseInt(listener.tPortField.getText());
 
972
                int    listenPort = Integer.parseInt(listener.portField.getText());
 
973
 
 
974
                InputStream  tmpIn1  = inputStream ;
 
975
                OutputStream tmpOut1 = null ;
 
976
 
 
977
                InputStream  tmpIn2  = null ;
 
978
                OutputStream tmpOut2 = null ;
 
979
 
 
980
                if ( tmpIn1 == null ) {
 
981
                    tmpIn1  = inSocket.getInputStream();
 
982
                }
 
983
 
 
984
                if ( inSocket != null ) {
 
985
                    tmpOut1 = inSocket.getOutputStream();
 
986
                }
 
987
 
 
988
                String         bufferedData = null ;
 
989
                StringBuffer   buf = null ;
 
990
 
 
991
                int index = listener.connections.indexOf( this );
 
992
 
 
993
                if (listener.isProxyBox.isSelected() || HTTPProxyHost != null) {
 
994
                    // Check if we're a proxy
 
995
                    byte[]       b = new byte[1];
 
996
 
 
997
                    buf = new StringBuffer();
 
998
                    String       s ;
 
999
 
 
1000
                    for ( ; ; ) {
 
1001
                        int len ;
 
1002
 
 
1003
                        len = tmpIn1.read(b, 0, 1);
 
1004
                        if ( len == -1 ) {
 
1005
                            break ;
 
1006
                        }
 
1007
                        s = new String( b );
 
1008
                        buf.append( s );
 
1009
                        if ( b[0] != '\n' ) {
 
1010
                            continue ;
 
1011
                        }
 
1012
                        break ;
 
1013
                    }
 
1014
 
 
1015
                    bufferedData = buf.toString();
 
1016
                    inputText.append( bufferedData );
 
1017
 
 
1018
                    if ( bufferedData.startsWith( "GET " ) ||
 
1019
                        bufferedData.startsWith( "POST " ) ||
 
1020
                        bufferedData.startsWith( "PUT " ) ||
 
1021
                        bufferedData.startsWith( "DELETE " ) ) {
 
1022
                        int  start, end ;
 
1023
                        URL  url ;
 
1024
 
 
1025
                        start = bufferedData.indexOf( ' ' ) + 1;
 
1026
                        while ( bufferedData.charAt(start) == ' ' ) {
 
1027
                            start++ ;
 
1028
                        }
 
1029
                        end   = bufferedData.indexOf( ' ', start );
 
1030
                        String urlString = bufferedData.substring( start, end );
 
1031
 
 
1032
                        if ( urlString.charAt(0) == '/' ) {
 
1033
                            urlString = urlString.substring(1);
 
1034
                        }
 
1035
                        if ( listener.isProxyBox.isSelected() ) {
 
1036
                            url = new URL( urlString );
 
1037
                            targetHost = url.getHost();
 
1038
                            targetPort = url.getPort();
 
1039
                            if ( targetPort == -1 ) {
 
1040
                                targetPort = 80 ;
 
1041
                            }
 
1042
 
 
1043
                            listener.tableModel.setValueAt( targetHost, index + 1,
 
1044
                                OUTHOST_COLUMN );
 
1045
                            bufferedData = bufferedData.substring( 0, start) +
 
1046
                            url.getFile() +
 
1047
                            bufferedData.substring( end );
 
1048
                        }
 
1049
                        else {
 
1050
                            url = new URL( "http://" + targetHost + ":" +
 
1051
                                targetPort + "/" + urlString );
 
1052
 
 
1053
                            listener.tableModel.setValueAt( targetHost, index + 1,
 
1054
                                OUTHOST_COLUMN );
 
1055
                            bufferedData = bufferedData.substring( 0, start) +
 
1056
                                url.toExternalForm() +
 
1057
                                bufferedData.substring( end );
 
1058
 
 
1059
                            targetHost = HTTPProxyHost ;
 
1060
                            targetPort = HTTPProxyPort ;
 
1061
                        }
 
1062
 
 
1063
                    }
 
1064
                }
 
1065
                else {
 
1066
                    //
 
1067
                    // Change Host: header to point to correct host
 
1068
                    //
 
1069
                    byte[] b1 = new byte[1];
 
1070
 
 
1071
                    buf = new StringBuffer();
 
1072
                    String s1;
 
1073
                    String lastLine = null ;
 
1074
 
 
1075
                    for ( ; ; ) {
 
1076
                        int len ;
 
1077
 
 
1078
                        len = tmpIn1.read(b1, 0, 1);
 
1079
                        if ( len == -1 ) {
 
1080
                            break ;
 
1081
                        }
 
1082
                        s1 = new String( b1 );
 
1083
                        buf.append( s1 );
 
1084
                        if ( b1[0] != '\n' ) {
 
1085
                            continue ;
 
1086
                        }
 
1087
                        // we have a complete line
 
1088
                        String line = buf.toString();
 
1089
 
 
1090
                        buf.setLength(0);
 
1091
                        // check to see if we have found Host: header
 
1092
                        if (line.startsWith("Host: ")) {
 
1093
                            // we need to update the hostname to target host
 
1094
                            String newHost = "Host: " + targetHost + ":" + listenPort + "\r\n";
 
1095
 
 
1096
                            bufferedData = bufferedData.concat(newHost);
 
1097
                            break ;
 
1098
                        }
 
1099
                        // add it to our headers so far
 
1100
                        if (bufferedData == null) {
 
1101
                            bufferedData = line;
 
1102
                        } else {
 
1103
                            bufferedData = bufferedData.concat(line);
 
1104
                        }
 
1105
 
 
1106
                        // failsafe
 
1107
                        if (line.equals("\r\n")) {
 
1108
                            break;
 
1109
                        }
 
1110
                        if ("\n".equals(lastLine) && line.equals("\n")) {
 
1111
                            break ;
 
1112
                        }
 
1113
                        lastLine = line ;
 
1114
                    }
 
1115
                    if ( bufferedData != null ) {
 
1116
                        inputText.append( bufferedData );
 
1117
                        int idx = bufferedData.length() < 50 ? bufferedData.length() : 50;
 
1118
                        s1 = bufferedData.substring( 0, idx );
 
1119
                        int i = s1.indexOf('\n');
 
1120
 
 
1121
                        if ( i > 0 ) {
 
1122
                            s1 = s1.substring(0, i - 1);
 
1123
                        }
 
1124
                        s1 = s1 + "                           " +
 
1125
                                  "                       ";
 
1126
                        s1 = s1.substring(0, 51);
 
1127
                        listener.tableModel.setValueAt( s1, index + 1,
 
1128
                            REQ_COLUMN );
 
1129
                    }
 
1130
                }
 
1131
 
 
1132
                if ( targetPort == -1 ) {
 
1133
                    targetPort = 80 ;
 
1134
                }
 
1135
                outSocket = new Socket(targetHost, targetPort );
 
1136
 
 
1137
                tmpIn2  = outSocket.getInputStream();
 
1138
                tmpOut2 = outSocket.getOutputStream();
 
1139
 
 
1140
                if ( bufferedData != null ) {
 
1141
                    byte[] b = bufferedData.getBytes();
 
1142
                    tmpOut2.write( b );
 
1143
                    slowLink.pump(b.length);
 
1144
                }
 
1145
 
 
1146
                boolean format = listener.xmlFormatBox.isSelected();
 
1147
                boolean numeric = listener.numericBox.isSelected();
 
1148
 
 
1149
 
 
1150
                //this is the channel to the endpoint
 
1151
                rr1 = new SocketRR(this, inSocket, tmpIn1, outSocket,
 
1152
                    tmpOut2, inputText, format, numeric,
 
1153
                    listener.tableModel, index + 1, "request:", slowLink);
 
1154
                //create the response slow link from the inbound slow link
 
1155
                SlowLinkSimulator responseLink = new SlowLinkSimulator(slowLink);
 
1156
                //this is the channel from the endpoint
 
1157
                rr2 = new SocketRR( this, outSocket, tmpIn2, inSocket,
 
1158
                    tmpOut1, outputText, format, numeric,
 
1159
                    null, 0, "response:", responseLink);
 
1160
 
 
1161
                while ( rr1 != null || rr2 != null ) {
 
1162
                    // Only loop as long as the connection to the target
 
1163
                    // machine is available - once that's gone we can stop.
 
1164
                    // The old way, loop until both are closed, left us
 
1165
                    // looping forever since no one closed the 1st one.
 
1166
                    // while( !rr2.isDone() )
 
1167
                    if (null != rr1 && rr1.isDone()) {
 
1168
                        if ( index >= 0  && rr2 != null) {
 
1169
                            listener.tableModel.setValueAt(getMessage("resp00", "Resp"),
 
1170
                                1 + index, STATE_COLUMN );
 
1171
                        }
 
1172
                       rr1 = null;
 
1173
                    }
 
1174
                    if (null != rr2 && rr2.isDone()) {
 
1175
                        if ( index >= 0 && rr1 != null ) {
 
1176
                            listener.tableModel.setValueAt(getMessage("req00", "Req"),
 
1177
                                1 + index, STATE_COLUMN );
 
1178
                        }
 
1179
                        rr2 = null;
 
1180
                    }
 
1181
 
 
1182
                    //  Thread.sleep( 10 );
 
1183
                    synchronized ( this) {
 
1184
                        this.wait(1000); //Safety just incase we're not told to wake up.
 
1185
                    }
 
1186
                }
 
1187
 
 
1188
                //  System.out.println("Done ");
 
1189
                // rr1.halt();
 
1190
                // rr2.halt();
 
1191
 
 
1192
 
 
1193
                active = false ;
 
1194
 
 
1195
                /*
 
1196
                 if ( inSocket != null ) {
 
1197
                 inSocket.close();
 
1198
                 inSocket = null ;
 
1199
                 }
 
1200
                 outSocket.close();
 
1201
                 outSocket = null ;
 
1202
                 */
 
1203
 
 
1204
                if ( index >= 0 ) {
 
1205
                    listener.tableModel.setValueAt(getMessage("done00", "Done"),
 
1206
                        1 + index, STATE_COLUMN );
 
1207
 
 
1208
                }
 
1209
            }
 
1210
            catch ( Exception e ) {
 
1211
                StringWriter st = new StringWriter();
 
1212
                PrintWriter  wr = new PrintWriter(st);
 
1213
                int index = listener.connections.indexOf( this );
 
1214
 
 
1215
                if ( index >= 0 ) {
 
1216
                    listener.tableModel.setValueAt( getMessage("error00", "Error"), 1 + index, STATE_COLUMN );
 
1217
                }
 
1218
                e.printStackTrace(wr);
 
1219
                wr.close();
 
1220
                if(outputText!=null) {
 
1221
                    outputText.append( st.toString() );
 
1222
                } else {
 
1223
                    //something went wrong before we had the output area
 
1224
                    System.out.println(st.toString());
 
1225
                }
 
1226
                halt();
 
1227
            }
 
1228
        }
 
1229
 
 
1230
        synchronized void wakeUp() {
 
1231
            this.notifyAll();
 
1232
        }
 
1233
 
 
1234
        public void halt() {
 
1235
            try {
 
1236
                if ( rr1 != null ) {
 
1237
                    rr1.halt();
 
1238
                }
 
1239
                if ( rr2 != null ) {
 
1240
                    rr2.halt();
 
1241
                }
 
1242
                if ( inSocket  != null ) {
 
1243
                    inSocket.close();
 
1244
                }
 
1245
                inSocket = null ;
 
1246
                if ( outSocket != null ) {
 
1247
                    outSocket.close();
 
1248
                }
 
1249
                outSocket = null ;
 
1250
            }
 
1251
            catch ( Exception e ) {
 
1252
                e.printStackTrace();
 
1253
            }
 
1254
        }
 
1255
 
 
1256
        public void remove() {
 
1257
            int index = -1;
 
1258
 
 
1259
            try {
 
1260
                halt();
 
1261
                index = listener.connections.indexOf( this );
 
1262
                listener.tableModel.removeRow( index + 1 );
 
1263
                listener.connections.remove( index );
 
1264
            }
 
1265
            catch ( Exception e ) {
 
1266
                System.err.println("index:=" + index + this );
 
1267
                e.printStackTrace();
 
1268
            }
 
1269
        }
 
1270
    }
 
1271
 
 
1272
 
 
1273
    /**
 
1274
     * this is one of the tabbed panels that acts as the actual proxy
 
1275
     */
 
1276
    class Listener extends JPanel {
 
1277
        public  Socket      inputSocket     = null ;
 
1278
        public  Socket      outputSocket    = null ;
 
1279
        public  JTextField  portField       = null ;
 
1280
        public  JTextField  hostField       = null ;
 
1281
        public  JTextField  tPortField      = null ;
 
1282
        public  JCheckBox   isProxyBox      = null ;
 
1283
        public  JButton     stopButton      = null ;
 
1284
        public  JButton     removeButton    = null ;
 
1285
        public  JButton     removeAllButton = null ;
 
1286
        public  JCheckBox   xmlFormatBox    = null ;
 
1287
        public  JCheckBox   numericBox      = null ;
 
1288
        public  JButton     saveButton      = null ;
 
1289
        public  JButton     resendButton    = null ;
 
1290
        public  JButton     switchButton    = null ;
 
1291
        public  JButton     closeButton     = null ;
 
1292
        public  JTable      connectionTable = null ;
 
1293
        public  DefaultTableModel  tableModel      = null ;
 
1294
        public  JSplitPane  outPane         = null ;
 
1295
        public  ServerSocket sSocket        = null ;
 
1296
        public  SocketWaiter sw = null ;
 
1297
        public  JPanel      leftPanel       = null ;
 
1298
        public  JPanel      rightPanel      = null ;
 
1299
        public  JTabbedPane notebook        = null ;
 
1300
        public  String      HTTPProxyHost   = null ;
 
1301
        public  int         HTTPProxyPort   = 80 ;
 
1302
        public  int         delayBytes      = 0;
 
1303
        public  int         delayTime       = 0;
 
1304
        public SlowLinkSimulator slowLink;
 
1305
 
 
1306
        public final Vector connections = new Vector();
 
1307
 
 
1308
        /**
 
1309
         * create a listener
 
1310
         * @param _notebook
 
1311
         * @param name
 
1312
         * @param listenPort
 
1313
         * @param host
 
1314
         * @param targetPort
 
1315
         * @param isProxy
 
1316
         * @param slowLink optional reference to a slow connection
 
1317
         */
 
1318
        public Listener(JTabbedPane _notebook, String name,
 
1319
            int listenPort, String host, int targetPort,
 
1320
            boolean isProxy, SlowLinkSimulator slowLink) {
 
1321
            notebook = _notebook ;
 
1322
            if ( name == null ) {
 
1323
                name = getMessage("port01", "Port") + " " + listenPort ;
 
1324
            }
 
1325
            //set the slow link to the passed down link
 
1326
            if(slowLink!=null) {
 
1327
                this.slowLink=slowLink;
 
1328
            } else {
 
1329
                //or make up a no-op one.
 
1330
                this.slowLink=new SlowLinkSimulator(0,0);
 
1331
            }
 
1332
            this.setLayout( new BorderLayout() );
 
1333
 
 
1334
            // 1st component is just a row of labels and 1-line entry fields
 
1335
            /////////////////////////////////////////////////////////////////////
 
1336
            JPanel top = new JPanel();
 
1337
 
 
1338
            top.setLayout( new BoxLayout(top, BoxLayout.X_AXIS) );
 
1339
            top.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
 
1340
            final String start = getMessage("start00", "Start");
 
1341
 
 
1342
            top.add( stopButton = new JButton( start ) );
 
1343
            top.add( Box.createRigidArea(new Dimension(5, 0)) );
 
1344
            top.add( new JLabel( "  " + getMessage("listenPort01", "Listen Port:") + " ", SwingConstants.RIGHT ) );
 
1345
            top.add( portField = new JTextField( "" + listenPort, 4 ) );
 
1346
            top.add( new JLabel( "  " + getMessage("host00", "Host:"), SwingConstants.RIGHT ) );
 
1347
            top.add( hostField = new JTextField( host, 30 ) );
 
1348
            top.add( new JLabel( "  " + getMessage("port02", "Port:") + " ", SwingConstants.RIGHT ) );
 
1349
            top.add( tPortField = new JTextField( "" + targetPort, 4 ) );
 
1350
            top.add( Box.createRigidArea(new Dimension(5, 0)) );
 
1351
            top.add( isProxyBox = new JCheckBox(getMessage("proxy00", "Proxy")) );
 
1352
 
 
1353
            isProxyBox.addChangeListener( new BasicButtonListener(isProxyBox) {
 
1354
                    public void stateChanged(ChangeEvent event) {
 
1355
                        JCheckBox box = (JCheckBox) event.getSource();
 
1356
                        boolean state = box.isSelected();
 
1357
 
 
1358
                        tPortField.setEnabled( !state );
 
1359
                        hostField.setEnabled( !state );
 
1360
                    }
 
1361
                }
 
1362
            );
 
1363
 
 
1364
            isProxyBox.setSelected(isProxy);
 
1365
 
 
1366
            portField.setEditable(false);
 
1367
            portField.setMaximumSize(new Dimension(50, Short.MAX_VALUE) );
 
1368
            hostField.setEditable(false);
 
1369
            hostField.setMaximumSize(new Dimension(85, Short.MAX_VALUE) );
 
1370
            tPortField.setEditable(false);
 
1371
            tPortField.setMaximumSize(new Dimension(50, Short.MAX_VALUE) );
 
1372
 
 
1373
            stopButton.addActionListener( new ActionListener() {
 
1374
                    public void actionPerformed(ActionEvent event) {
 
1375
                        if ( getMessage("stop00", "Stop").equals(event.getActionCommand()) ) {
 
1376
                            stop();
 
1377
                        }
 
1378
                        if ( start.equals(event.getActionCommand()) ) {
 
1379
                            start();
 
1380
                        }
 
1381
                    }
 
1382
                }
 
1383
            );
 
1384
 
 
1385
            this.add( top, BorderLayout.NORTH );
 
1386
 
 
1387
            // 2nd component is a split pane with a table on the top
 
1388
            // and the request/response text areas on the bottom
 
1389
            /////////////////////////////////////////////////////////////////////
 
1390
 
 
1391
            tableModel = new DefaultTableModel(new String[] {
 
1392
                    getMessage("state00", "State"),
 
1393
                    getMessage("time00", "Time"),
 
1394
                    getMessage("requestHost00", "Request Host"),
 
1395
                    getMessage("targetHost", "Target Host"),
 
1396
                    getMessage("request00", "Request...")
 
1397
                } , 0 );
 
1398
 
 
1399
            tableModel.addRow( new Object[] {
 
1400
                    "---", getMessage("mostRecent00", "Most Recent"), "---", "---", "---"
 
1401
                }
 
1402
            );
 
1403
 
 
1404
            connectionTable = new JTable(1, 2);
 
1405
            connectionTable.setModel( tableModel );
 
1406
            connectionTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
 
1407
            // Reduce the STATE column and increase the REQ column
 
1408
            TableColumn col ;
 
1409
 
 
1410
            col = connectionTable.getColumnModel().getColumn(STATE_COLUMN);
 
1411
            col.setMaxWidth( col.getPreferredWidth() / 2 );
 
1412
            col = connectionTable.getColumnModel().getColumn(REQ_COLUMN);
 
1413
            col.setPreferredWidth( col.getPreferredWidth() * 2 );
 
1414
 
 
1415
 
 
1416
            ListSelectionModel sel = connectionTable.getSelectionModel();
 
1417
 
 
1418
            sel.addListSelectionListener( new ListSelectionListener() {
 
1419
                    public void valueChanged(ListSelectionEvent event) {
 
1420
                        if (event.getValueIsAdjusting()) {
 
1421
                            return ;
 
1422
                        }
 
1423
                        ListSelectionModel m = (ListSelectionModel) event.getSource();
 
1424
                        int divLoc = outPane.getDividerLocation();
 
1425
 
 
1426
                        if (m.isSelectionEmpty()) {
 
1427
                            setLeft( new JLabel(" " + getMessage("wait00", "Waiting for Connection...") ) );
 
1428
                            setRight( new JLabel("") );
 
1429
                            removeButton.setEnabled(false);
 
1430
                            removeAllButton.setEnabled(false);
 
1431
                            saveButton.setEnabled(false);
 
1432
                            resendButton.setEnabled(false);
 
1433
                        }
 
1434
                        else {
 
1435
                            int row = m.getLeadSelectionIndex();
 
1436
 
 
1437
                            if ( row == 0 ) {
 
1438
                                if ( connections.size() == 0 ) {
 
1439
                                    setLeft(new JLabel(" " + getMessage("wait00", "Waiting for connection...")));
 
1440
                                    setRight(new JLabel(""));
 
1441
                                    removeButton.setEnabled(false);
 
1442
                                    removeAllButton.setEnabled(false);
 
1443
                                    saveButton.setEnabled(false);
 
1444
                                    resendButton.setEnabled(false);
 
1445
                                }
 
1446
                                else {
 
1447
                                    Connection conn = (Connection) connections.lastElement();
 
1448
 
 
1449
                                    setLeft( conn.inputScroll );
 
1450
                                    setRight( conn.outputScroll );
 
1451
                                    removeButton.setEnabled(false);
 
1452
                                    removeAllButton.setEnabled(true);
 
1453
                                    saveButton.setEnabled(true);
 
1454
                                    resendButton.setEnabled(true);
 
1455
                                }
 
1456
                            }
 
1457
                            else {
 
1458
                                Connection conn = (Connection) connections.get(row - 1);
 
1459
 
 
1460
                                setLeft( conn.inputScroll );
 
1461
                                setRight( conn.outputScroll );
 
1462
                                removeButton.setEnabled(true);
 
1463
                                removeAllButton.setEnabled(true);
 
1464
                                saveButton.setEnabled(true);
 
1465
                                resendButton.setEnabled(true);
 
1466
                            }
 
1467
                        }
 
1468
                        outPane.setDividerLocation(divLoc);
 
1469
                    }
 
1470
                }
 
1471
            );
 
1472
 
 
1473
            JPanel  tablePane = new JPanel();
 
1474
 
 
1475
            tablePane.setLayout( new BorderLayout() );
 
1476
 
 
1477
            JScrollPane tableScrollPane = new JScrollPane( connectionTable );
 
1478
 
 
1479
            tablePane.add( tableScrollPane, BorderLayout.CENTER );
 
1480
            JPanel buttons = new JPanel();
 
1481
 
 
1482
            buttons.setLayout( new BoxLayout(buttons, BoxLayout.X_AXIS) );
 
1483
            buttons.setBorder( BorderFactory.createEmptyBorder(5, 5, 5, 5) );
 
1484
            final String removeSelected = getMessage("removeSelected00", "Remove Selected");
 
1485
 
 
1486
            buttons.add( removeButton = new JButton(removeSelected) );
 
1487
            buttons.add( Box.createRigidArea(new Dimension(5, 0)) );
 
1488
            final String removeAll = getMessage("removeAll00", "Remove All");
 
1489
 
 
1490
            buttons.add( removeAllButton = new JButton(removeAll) );
 
1491
            tablePane.add( buttons, BorderLayout.SOUTH );
 
1492
 
 
1493
            removeButton.setEnabled( false );
 
1494
            removeButton.addActionListener( new ActionListener() {
 
1495
                    public void actionPerformed(ActionEvent event) {
 
1496
                        if ( removeSelected.equals(event.getActionCommand()) ) {
 
1497
                            remove();
 
1498
                        }
 
1499
                    }
 
1500
                }
 
1501
            );
 
1502
 
 
1503
            removeAllButton.setEnabled( false );
 
1504
            removeAllButton.addActionListener( new ActionListener() {
 
1505
                    public void actionPerformed(ActionEvent event) {
 
1506
                        if ( removeAll.equals(event.getActionCommand()) ) {
 
1507
                            removeAll();
 
1508
                        }
 
1509
                    }
 
1510
                }
 
1511
            );
 
1512
 
 
1513
            // Add Response Section
 
1514
            /////////////////////////////////////////////////////////////////////
 
1515
            JPanel     pane2     = new JPanel();
 
1516
 
 
1517
            pane2.setLayout( new BorderLayout() );
 
1518
 
 
1519
            leftPanel = new JPanel();
 
1520
            leftPanel.setAlignmentX( Component.LEFT_ALIGNMENT );
 
1521
            leftPanel.setLayout( new BoxLayout(leftPanel, BoxLayout.Y_AXIS) );
 
1522
            leftPanel.add( new JLabel("  " + getMessage("request01", "Request")) );
 
1523
            leftPanel.add( new JLabel(" " + getMessage("wait01", "Waiting for connection") ));
 
1524
 
 
1525
            rightPanel = new JPanel();
 
1526
            rightPanel.setLayout( new BoxLayout(rightPanel, BoxLayout.Y_AXIS) );
 
1527
            rightPanel.add( new JLabel("  " + getMessage("response00", "Response")) );
 
1528
            rightPanel.add( new JLabel("") );
 
1529
 
 
1530
            outPane = new JSplitPane(0, leftPanel, rightPanel );
 
1531
            outPane.setDividerSize(4);
 
1532
            pane2.add( outPane, BorderLayout.CENTER );
 
1533
 
 
1534
            JPanel bottomButtons = new JPanel();
 
1535
 
 
1536
            bottomButtons.setLayout( new BoxLayout(bottomButtons, BoxLayout.X_AXIS));
 
1537
            bottomButtons.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
 
1538
            bottomButtons.add( xmlFormatBox = new JCheckBox( getMessage("xmlFormat00", "XML Format") ) );
 
1539
            bottomButtons.add( numericBox = new JCheckBox( getMessage("numericEnc00", "Numeric" ) ) );
 
1540
            bottomButtons.add( Box.createRigidArea(new Dimension(5, 0)) );
 
1541
            final String save = getMessage("save00", "Save");
 
1542
 
 
1543
            bottomButtons.add( saveButton = new JButton( save ) );
 
1544
            bottomButtons.add( Box.createRigidArea(new Dimension(5, 0)) );
 
1545
            final String resend = getMessage("resend00", "Resend");
 
1546
 
 
1547
            bottomButtons.add( resendButton = new JButton( resend ) );
 
1548
            bottomButtons.add( Box.createRigidArea(new Dimension(5, 0)) );
 
1549
            final String switchStr = getMessage("switch00", "Switch Layout");
 
1550
 
 
1551
            bottomButtons.add( switchButton = new JButton( switchStr ) );
 
1552
            bottomButtons.add( Box.createHorizontalGlue() );
 
1553
            final String close = getMessage("close00", "Close");
 
1554
 
 
1555
            bottomButtons.add( closeButton = new JButton( close ) );
 
1556
            pane2.add( bottomButtons, BorderLayout.SOUTH );
 
1557
 
 
1558
            saveButton.setEnabled( false );
 
1559
            saveButton.addActionListener( new ActionListener() {
 
1560
                    public void actionPerformed(ActionEvent event) {
 
1561
                        if ( save.equals(event.getActionCommand()) ) {
 
1562
                            save();
 
1563
                        }
 
1564
                    }
 
1565
                }
 
1566
            );
 
1567
 
 
1568
            resendButton.setEnabled( false );
 
1569
            resendButton.addActionListener( new ActionListener() {
 
1570
                    public void actionPerformed(ActionEvent event) {
 
1571
                        if ( resend.equals(event.getActionCommand()) ) {
 
1572
                            resend();
 
1573
                        }
 
1574
                    }
 
1575
                }
 
1576
            );
 
1577
 
 
1578
            switchButton.addActionListener( new ActionListener() {
 
1579
                    public void actionPerformed(ActionEvent event) {
 
1580
                        if (switchStr.equals(event.getActionCommand()) ) {
 
1581
                            int v = outPane.getOrientation();
 
1582
 
 
1583
                            if ( v == 0 ) {
 
1584
                                // top/bottom
 
1585
                                outPane.setOrientation(1);
 
1586
                            }
 
1587
                            else  {
 
1588
                                // left/right
 
1589
                                outPane.setOrientation(0);
 
1590
                            }
 
1591
                            outPane.setDividerLocation(0.5);
 
1592
                        }
 
1593
                    }
 
1594
                }
 
1595
            );
 
1596
 
 
1597
            closeButton.addActionListener( new ActionListener() {
 
1598
                    public void actionPerformed(ActionEvent event) {
 
1599
                        if (close.equals(event.getActionCommand()) ) {
 
1600
                            close();
 
1601
                        }
 
1602
                    }
 
1603
                }
 
1604
            );
 
1605
 
 
1606
            JSplitPane  pane1 = new JSplitPane( 0 );
 
1607
 
 
1608
            pane1.setDividerSize(4);
 
1609
            pane1.setTopComponent( tablePane );
 
1610
            pane1.setBottomComponent( pane2 );
 
1611
            pane1.setDividerLocation( 150 );
 
1612
            this.add( pane1, BorderLayout.CENTER );
 
1613
 
 
1614
            //
 
1615
            ////////////////////////////////////////////////////////////////////
 
1616
            sel.setSelectionInterval(0, 0);
 
1617
            outPane.setDividerLocation( 150 );
 
1618
            notebook.addTab( name, this );
 
1619
            start();
 
1620
        }
 
1621
 
 
1622
        public void setLeft(Component left) {
 
1623
            leftPanel.removeAll();
 
1624
            leftPanel.add(left);
 
1625
        }
 
1626
 
 
1627
        public void setRight(Component right) {
 
1628
            rightPanel.removeAll();
 
1629
            rightPanel.add(right);
 
1630
        }
 
1631
 
 
1632
        public void start() {
 
1633
            int  port = Integer.parseInt( portField.getText() );
 
1634
 
 
1635
            portField.setText( "" + port );
 
1636
            int i = notebook.indexOfComponent( this );
 
1637
 
 
1638
            notebook.setTitleAt( i, getMessage("port01", "Port") + " " + port );
 
1639
 
 
1640
            int  tmp = Integer.parseInt( tPortField.getText() );
 
1641
 
 
1642
            tPortField.setText( "" + tmp );
 
1643
 
 
1644
            sw = new SocketWaiter( this, port );
 
1645
            stopButton.setText( getMessage("stop00", "Stop") );
 
1646
 
 
1647
            portField.setEditable(false);
 
1648
            hostField.setEditable(false);
 
1649
            tPortField.setEditable(false);
 
1650
            isProxyBox.setEnabled(false);
 
1651
        }
 
1652
 
 
1653
        public void close() {
 
1654
            stop();
 
1655
            notebook.remove( this );
 
1656
        }
 
1657
 
 
1658
        public void stop() {
 
1659
            try {
 
1660
                for ( int i = 0 ; i < connections.size() ; i++ ) {
 
1661
                    Connection conn = (Connection) connections.get( i );
 
1662
 
 
1663
                    conn.halt();
 
1664
                }
 
1665
                sw.halt();
 
1666
                stopButton.setText( getMessage("start00", "Start") );
 
1667
                portField.setEditable(true);
 
1668
                hostField.setEditable(true);
 
1669
                tPortField.setEditable(true);
 
1670
                isProxyBox.setEnabled(true);
 
1671
            }
 
1672
            catch ( Exception e ) {
 
1673
                e.printStackTrace();
 
1674
            }
 
1675
        }
 
1676
 
 
1677
        public void remove() {
 
1678
            ListSelectionModel lsm = connectionTable.getSelectionModel();
 
1679
            int bot = lsm.getMinSelectionIndex();
 
1680
            int top = lsm.getMaxSelectionIndex();
 
1681
 
 
1682
            for ( int i = top ; i >= bot ; i-- ) {
 
1683
                ((Connection) connections.get(i - 1)).remove();
 
1684
            }
 
1685
            if ( bot > connections.size() ) {
 
1686
                bot = connections.size();
 
1687
            }
 
1688
            lsm.setSelectionInterval(bot, bot);
 
1689
        }
 
1690
 
 
1691
        public void removeAll() {
 
1692
            ListSelectionModel lsm = connectionTable.getSelectionModel();
 
1693
            lsm.clearSelection();
 
1694
            while ( connections.size() > 0 ) {
 
1695
                ((Connection) connections.get(0)).remove();
 
1696
            }
 
1697
 
 
1698
            lsm.setSelectionInterval(0, 0);
 
1699
        }
 
1700
 
 
1701
        public void save() {
 
1702
            JFileChooser  dialog = new JFileChooser( "." );
 
1703
            int rc = dialog.showSaveDialog( this );
 
1704
 
 
1705
            if ( rc == JFileChooser.APPROVE_OPTION ) {
 
1706
                try {
 
1707
                    File             file = dialog.getSelectedFile();
 
1708
                    FileOutputStream out  = new FileOutputStream( file );
 
1709
 
 
1710
                    ListSelectionModel lsm = connectionTable.getSelectionModel();
 
1711
 
 
1712
                    rc = lsm.getLeadSelectionIndex();
 
1713
 
 
1714
                    int n = 0;
 
1715
                    for (Iterator i = connections.iterator();i.hasNext();n++) {
 
1716
                      Connection conn = (Connection)i.next();
 
1717
                      if (lsm.isSelectedIndex(n + 1) ||
 
1718
                                   (!(i.hasNext()) && lsm.getLeadSelectionIndex() == 0)) {
 
1719
                        rc = Integer.parseInt( portField.getText() );
 
1720
                        out.write("\n==============\n".getBytes());
 
1721
                        out.write( ((getMessage("listenPort01", "Listen Port:") + " " + rc + "\n" )).getBytes() );
 
1722
                        out.write( (getMessage("targetHost01", "Target Host:") + " " + hostField.getText() +
 
1723
                                    "\n" ).getBytes() );
 
1724
                        rc = Integer.parseInt( tPortField.getText() );
 
1725
                        out.write( ((getMessage("targetPort01", "Target Port:") + " " + rc + "\n" )).getBytes() );
 
1726
 
 
1727
                        out.write( (("==== " + getMessage("request01", "Request") + " ====\n" )).getBytes() );
 
1728
                        out.write( conn.inputText.getText().getBytes() );
 
1729
 
 
1730
                        out.write( (("==== " + getMessage("response00", "Response") + " ====\n" )).getBytes() );
 
1731
                        out.write( conn.outputText.getText().getBytes() );
 
1732
                        out.write("\n==============\n".getBytes());
 
1733
                      }
 
1734
                    }
 
1735
 
 
1736
                    out.close();
 
1737
                }
 
1738
                catch ( Exception e ) {
 
1739
                    e.printStackTrace();
 
1740
                }
 
1741
            }
 
1742
        }
 
1743
 
 
1744
        public void resend() {
 
1745
            int rc ;
 
1746
 
 
1747
            try {
 
1748
                ListSelectionModel lsm = connectionTable.getSelectionModel();
 
1749
 
 
1750
                rc = lsm.getLeadSelectionIndex();
 
1751
                if ( rc == 0 ) {
 
1752
                    rc = connections.size();
 
1753
                }
 
1754
                Connection conn = (Connection) connections.get( rc - 1 );
 
1755
 
 
1756
                if ( rc > 0 ) {
 
1757
                    lsm.clearSelection();
 
1758
                    lsm.setSelectionInterval(0, 0);
 
1759
                }
 
1760
 
 
1761
                InputStream in = null ;
 
1762
                String      text = conn.inputText.getText();
 
1763
 
 
1764
                // Fix Content-Length HTTP headers
 
1765
                if ( text.startsWith("POST ") || text.startsWith("GET ") ) {
 
1766
                    // System.err.println("IN CL" );
 
1767
                    int         pos1, pos2, pos3 ;
 
1768
                    String      body, headers, headers1, header2 ;
 
1769
 
 
1770
                    pos3 = text.indexOf( "\n\n" );
 
1771
                    if ( pos3 == -1 ) {
 
1772
                        pos3 = text.indexOf( "\r\n\r\n" );
 
1773
                        if ( pos3 != -1 ) {
 
1774
                            pos3 = pos3 + 4 ;
 
1775
                        }
 
1776
                    }
 
1777
                    else {
 
1778
                        pos3 += 2 ;
 
1779
                    }
 
1780
 
 
1781
                    headers = text.substring( 0, pos3 );
 
1782
 
 
1783
                    pos1 = headers.indexOf( "Content-Length:" );
 
1784
                    // System.err.println("pos1: " + pos1 );
 
1785
                    // System.err.println("pos3: " + pos3 );
 
1786
                    if ( pos1 != -1 ) {
 
1787
                        int  newLen = text.length() - pos3 ;
 
1788
 
 
1789
                        pos2 = headers.indexOf( "\n", pos1 );
 
1790
 
 
1791
                        System.err.println("CL: " + newLen );
 
1792
                        System.err.println("Hdrs: '" + headers + "'" );
 
1793
                        System.err.println("subTEXT: '" +
 
1794
                            text.substring(pos3, pos3 + newLen) + "'");
 
1795
                        text = headers.substring(0, pos1) +
 
1796
                        "Content-Length: " + newLen + "\n" +
 
1797
                        headers.substring(pos2 + 1) +
 
1798
                        text.substring(pos3) ;
 
1799
                        System.err.println("\nTEXT: '" + text + "'" );
 
1800
                    }
 
1801
                }
 
1802
 
 
1803
                in = new ByteArrayInputStream( text.getBytes() );
 
1804
                new Connection( this, in );
 
1805
            }
 
1806
            catch ( Exception e ) {
 
1807
                e.printStackTrace();
 
1808
            }
 
1809
        }
 
1810
    }
 
1811
 
 
1812
 
 
1813
    public tcpmon(int listenPort, String targetHost, int targetPort, boolean embedded) {
 
1814
        super ( getMessage("tcpmon00", "TCPMonitor") );
 
1815
 
 
1816
        notebook = new JTabbedPane();
 
1817
        this.getContentPane().add( notebook );
 
1818
 
 
1819
        new AdminPage( notebook, getMessage("admin00", "Admin") );
 
1820
 
 
1821
        if ( listenPort != 0 ) {
 
1822
            Listener l = null ;
 
1823
 
 
1824
            if ( targetHost == null ) {
 
1825
                l = new Listener( notebook, null, listenPort,
 
1826
                    targetHost, targetPort, true, null);
 
1827
            } else {
 
1828
                l = new Listener( notebook, null, listenPort,
 
1829
                    targetHost, targetPort, false, null);
 
1830
            }
 
1831
            notebook.setSelectedIndex( 1 );
 
1832
 
 
1833
            l.HTTPProxyHost = System.getProperty( "http.proxyHost" );
 
1834
            if ( l.HTTPProxyHost != null && l.HTTPProxyHost.equals("") ) {
 
1835
                l.HTTPProxyHost = null ;
 
1836
            }
 
1837
 
 
1838
            if ( l.HTTPProxyHost != null ) {
 
1839
                String tmp = System.getProperty( "http.proxyPort" );
 
1840
 
 
1841
                if ( tmp != null && tmp.equals("") ) {
 
1842
                    tmp = null ;
 
1843
                }
 
1844
                if ( tmp == null ) {
 
1845
                    l.HTTPProxyPort = 80 ;
 
1846
                } else {
 
1847
                    l.HTTPProxyPort = Integer.parseInt( tmp );
 
1848
                }
 
1849
            }
 
1850
        }
 
1851
        
 
1852
        if(!embedded) {
 
1853
            this.setDefaultCloseOperation(EXIT_ON_CLOSE);
 
1854
        }
 
1855
        this.pack();
 
1856
        this.setSize( 600, 600 );
 
1857
        this.setVisible( true );
 
1858
    }
 
1859
    
 
1860
    public tcpmon(int listenPort, String targetHost, int targetPort) {
 
1861
        this(listenPort, targetHost, targetPort, false);
 
1862
    }
 
1863
 
 
1864
    /**
 
1865
     * set up the L&F
 
1866
     */
 
1867
    private static void setupLookAndFeel(boolean nativeLookAndFeel) throws Exception {
 
1868
        String classname= UIManager.getCrossPlatformLookAndFeelClassName();
 
1869
        if(nativeLookAndFeel) {
 
1870
            classname= UIManager.getSystemLookAndFeelClassName();
 
1871
        }
 
1872
        String lafProperty= System.getProperty("tcpmon.laf", "");
 
1873
        if(lafProperty.length()>0) {
 
1874
            classname=lafProperty;
 
1875
        }
 
1876
        try {
 
1877
            UIManager.setLookAndFeel(classname);
 
1878
        } catch (ClassNotFoundException e) {
 
1879
            e.printStackTrace();
 
1880
        } catch (InstantiationException e) {
 
1881
            e.printStackTrace();
 
1882
        } catch (IllegalAccessException e) {
 
1883
            e.printStackTrace();
 
1884
        } catch (UnsupportedLookAndFeelException e) {
 
1885
            e.printStackTrace();
 
1886
        }
 
1887
    }
 
1888
    /**
 
1889
     * this is our main method
 
1890
     * @param args
 
1891
     */
 
1892
    public static void main(String[] args) {
 
1893
        try {
 
1894
            //switch between swing L&F here
 
1895
            setupLookAndFeel(true);
 
1896
            if ( args.length == 3 ) {
 
1897
                int p1 = Integer.parseInt( args[0] );
 
1898
                int p2 = Integer.parseInt( args[2] );
 
1899
 
 
1900
                new tcpmon( p1, args[1], p2 );
 
1901
            }
 
1902
            else if ( args.length == 1 ) {
 
1903
                int p1 = Integer.parseInt( args[0] );
 
1904
 
 
1905
                new tcpmon( p1, null, 0 );
 
1906
            }
 
1907
            else if ( args.length != 0 ) {
 
1908
                System.err.println( getMessage("usage00", "Usage:")
 
1909
                        + " tcpmon [listenPort targetHost targetPort]\n");
 
1910
            }
 
1911
            else {
 
1912
                new tcpmon(0, null, 0);
 
1913
            }
 
1914
        }
 
1915
        catch ( Throwable exp ) {
 
1916
            exp.printStackTrace();
 
1917
        }
 
1918
    }
 
1919
 
 
1920
    // Message resource bundle.
 
1921
    private static ResourceBundle messages = null;
 
1922
 
 
1923
    /**
 
1924
     * Get the message with the given key.  There are no arguments for this message.
 
1925
     */
 
1926
    public static String getMessage(String key, String defaultMsg) {
 
1927
        try {
 
1928
            if (messages == null) {
 
1929
                initializeMessages();
 
1930
            }
 
1931
            return messages.getString(key);
 
1932
        } catch (Throwable t) {
 
1933
            // If there is any problem whatsoever getting the internationalized
 
1934
            // message, return the default.
 
1935
            return defaultMsg;
 
1936
        }
 
1937
    } // getMessage
 
1938
 
 
1939
    /**
 
1940
     * Load the resource bundle messages from the properties file.  This is ONLY done when it is
 
1941
     * needed.  If no messages are printed (for example, only Wsdl2java is being run in non-
 
1942
     * verbose mode) then there is no need to read the properties file.
 
1943
     */
 
1944
    private static void initializeMessages() {
 
1945
        messages = ResourceBundle.getBundle("org.apache.axis.utils.tcpmon");
 
1946
    } // initializeMessages
 
1947
 
 
1948
    /**
 
1949
     * a text field with a restricted set of characters
 
1950
     */
 
1951
    static class RestrictedTextField extends JTextField {
 
1952
        protected String validText;
 
1953
 
 
1954
        public RestrictedTextField(String validText) {
 
1955
            setValidText(validText);
 
1956
        }
 
1957
 
 
1958
        public RestrictedTextField(int columns, String validText) {
 
1959
            super(columns);
 
1960
            setValidText(validText);
 
1961
        }
 
1962
 
 
1963
        public RestrictedTextField(String text, String validText) {
 
1964
            super(text);
 
1965
            setValidText(validText);
 
1966
        }
 
1967
 
 
1968
        public RestrictedTextField(String text, int columns, String validText) {
 
1969
            super(text, columns);
 
1970
            setValidText(validText);
 
1971
        }
 
1972
 
 
1973
        private void setValidText(String validText) {
 
1974
            this.validText = validText;
 
1975
        }
 
1976
 
 
1977
        /**
 
1978
         * fascinatingly, this method is called in the super() constructor,
 
1979
         * meaning before we are fully initialized. C++ doesnt actually permit
 
1980
         * such a situation, but java clearly does...
 
1981
         * @return a new document
 
1982
         */
 
1983
        public Document createDefaultModel() {
 
1984
            return new RestrictedDocument();
 
1985
        }
 
1986
 
 
1987
        /**
 
1988
         * this class strips out invaid chars
 
1989
         */
 
1990
        class RestrictedDocument extends PlainDocument {
 
1991
 
 
1992
 
 
1993
            /**
 
1994
             * Constructs a plain text document.  A default model using
 
1995
             * <code>GapContent</code> is constructed and set.
 
1996
             */
 
1997
            public RestrictedDocument() {
 
1998
 
 
1999
            }
 
2000
 
 
2001
            /**
 
2002
             * add a string; only those chars in the valid text list are allowed
 
2003
             * @param offset
 
2004
             * @param string
 
2005
             * @param attributes
 
2006
             * @throws BadLocationException
 
2007
             */
 
2008
            public void insertString(int offset, String string, AttributeSet attributes)
 
2009
                    throws BadLocationException {
 
2010
 
 
2011
                if (string == null) {
 
2012
                    return;
 
2013
                }
 
2014
                int len = string.length();
 
2015
                StringBuffer buffer = new StringBuffer(string.length());
 
2016
                for (int i = 0; i < len; i++) {
 
2017
                    char ch = string.charAt(i);
 
2018
                    if (validText.indexOf(ch) >= 0) {
 
2019
                        buffer.append(ch);
 
2020
                    }
 
2021
                }
 
2022
                super.insertString(offset, new String(buffer), attributes);
 
2023
            }
 
2024
        } //end class NumericDocument
 
2025
    }
 
2026
 
 
2027
    /**
 
2028
     * because we cant use Java1.4's JFormattedTextField, here is
 
2029
     * a class that accepts numbers only
 
2030
     */
 
2031
    static class NumberField extends RestrictedTextField {
 
2032
 
 
2033
        private static final String VALID_TEXT = "0123456789";
 
2034
 
 
2035
        /**
 
2036
         * Constructs a new <code>TextField</code>.  A default model is created,
 
2037
         * the initial string is <code>null</code>,
 
2038
         * and the number of columns is set to 0.
 
2039
         */
 
2040
        public NumberField() {
 
2041
            super(VALID_TEXT);
 
2042
        }
 
2043
 
 
2044
        /**
 
2045
         * Constructs a new empty <code>TextField</code> with the specified
 
2046
         * number of columns.
 
2047
         * A default model is created and the initial string is set to
 
2048
         * <code>null</code>.
 
2049
         *
 
2050
         * @param columns  the number of columns to use to calculate
 
2051
         *   the preferred width; if columns is set to zero, the
 
2052
         *   preferred width will be whatever naturally results from
 
2053
         *   the component implementation
 
2054
         */
 
2055
        public NumberField(int columns) {
 
2056
            super(columns, VALID_TEXT);
 
2057
        }
 
2058
 
 
2059
 
 
2060
        /**
 
2061
         * get the int value of a field, any invalid (non int) field returns
 
2062
         * the default
 
2063
         * @param def default value
 
2064
         * @return the field contents
 
2065
         */
 
2066
        public int getValue(int def) {
 
2067
            int result = def;
 
2068
            String text = getText();
 
2069
            if (text != null && text.length() != 0) {
 
2070
                try {
 
2071
                    result = Integer.parseInt(text);
 
2072
                } catch (NumberFormatException e) {
 
2073
 
 
2074
                }
 
2075
            }
 
2076
            return result;
 
2077
        }
 
2078
 
 
2079
        /**
 
2080
         * set the text to a numeric value
 
2081
         * @param value number to assign
 
2082
         */
 
2083
        public void setValue(int value) {
 
2084
            setText(Integer.toString(value));
 
2085
        }
 
2086
 
 
2087
    } //end class NumericTextField
 
2088
 
 
2089
    /**
 
2090
     * hostname fields
 
2091
     */
 
2092
    static class HostnameField extends RestrictedTextField {
 
2093
        //list of valid chars in a hostname
 
2094
        private static final String VALID_TEXT =
 
2095
                "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWZYZ-.";
 
2096
 
 
2097
        public HostnameField(int columns) {
 
2098
            super(columns, VALID_TEXT);
 
2099
        }
 
2100
 
 
2101
        public HostnameField() {
 
2102
            super(VALID_TEXT);
 
2103
        }
 
2104
    }
 
2105
 
 
2106
}