--- /dev/null
+package org.wamblee.socketproxy;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Forwarder thread which handles forwarding of an input stream to
+ * an output stream.
+ */
+
+public class ForwarderThread extends Thread {
+
+ private String _prefix;
+
+ private Barrier _barrier;
+
+ private InputStream _is;
+
+ private OutputStream _os;
+
+ /**
+ * Constructs the forwarder thread.
+ * @param aPrefix Prefix to use in the output.
+ * @param aBarrier Barrier to block on before actually closing the stream.
+ * This is done to make sure that connections are only closed in th e
+ * proxy when the forwarders in both directions are ready to close.
+ * @param aIs Input stream to read from.
+ * @param aOs Output stream to forward to.
+ */
+ public ForwarderThread( String aPrefix, Barrier aBarrier,
+ InputStream aIs, OutputStream aOs ) {
+ _prefix = aPrefix;
+ _is = aIs;
+ _os = aOs;
+ _barrier = aBarrier;
+ }
+
+ public void run( ) {
+ boolean firstChar = true;
+ try {
+ int c = _is.read( );
+ while ( c > 0 ) {
+ try {
+ _os.write( c );
+ _os.flush( );
+ if ( firstChar ) {
+ System.out.print( _prefix );
+ firstChar = false;
+ }
+ System.out.print( (char) c );
+ if ( c == '\n' ) {
+ firstChar = true;
+ }
+ } catch ( IOException e ) {
+ }
+
+ c = _is.read( );
+ }
+ } catch ( IOException e ) {
+ }
+ closeStreams();
+ }
+
+ /**
+ * @param is
+ * @param os
+ */
+ private void closeStreams( ) {
+ _barrier.block( ); // wait until the other forwarder for the other direction
+ // is also closed.
+ try {
+ _is.close( );
+ } catch ( IOException e1 ) {
+ // Empty.
+ }
+ try {
+ _os.flush( );
+ _os.close( );
+ } catch ( IOException e1 ) {
+ // Empty
+ }
+ System.out.println(_prefix + " closed");
+ }
+
+}