views:

144

answers:

1

I'm trying to create a small HTTP proxy that can re-write the request/headers as needed to suit my requirements. If one already exists, please, point me to it. Otherwise...

I've written something that ALMOST works. It can do the proxy function, but not the re-write (yet). Problem is, I can't detect when the remote socket has been closed down without doing a blocking read. It is CRITICAL for the functionality of this thing that it be able to detect the socket being closed without blocking. I have SCOURED the Java API documentation, and I can't find ANY indication that it is even possible. Here's what I have:

    while ( this.inbound.isConnected() && this.outbound.isConnected() ) { 

      try {
        while ( ( available = readFromClient.available() ) != 0 ) { 
          if ( available > 1024 ) available = 1024
          bytesRead = readFromClient.read( buffer, 0, available )
          writeToServer.write( buffer, 0, bytesRead )
        }   

        while ( ( available = readFromServer.available() ) != 0 ) { 
          if ( available > 1024 ) available = 1024
          bytesRead = readFromServer.read( buffer, 0, available )
          writeToClient.write( buffer, 0, bytesRead )
        }                                                                                       
      } catch (e) { 
        print e
      }   

      println "Connected:      " + this.inbound.isConnected() 
      println "Bound:          " + this.inbound.isBound() 
      println "InputShutdown:  " + this.inbound.isInputShutdown() 
      println "OutputShutdown: " + this.inbound.isOutputShutdown() 
      print "\n";

      Thread.sleep( 10 )

    }   

The tests for the socket being closed never indicate that the socket was closed. And, as I mentioned, I can't find ANY examples of how to detect the 'END OF FILE' condition on the stream without doing a blocking read.

There HAS to be a way. Does anyone here know what it is?

+1  A: 

I'm assuming you're using java.net.Socket for your I/O. In order to do non-blocking I/O in Java, you have to use the NIO package.

In particular, you'll want to use a java.nio.channels.SocketChannel for communication. Call configureBlocking(false) on the channel, then read() will either return the amount of data read, -1 for closed, or zero if no data is available. An exception could be thrown on some error conditions as well.

Here's an example showing non-blocking I/O using a SocketChannel.

ataylor