package com.limegroup.gnutella.handshaking; import java.io.IOException; import java.net.Socket; import java.net.SocketException; import java.util.List; import java.util.Properties; import org.limewire.logging.Log; import org.limewire.logging.LogFactory; import org.limewire.nio.channel.NIOMultiplexor; import org.limewire.nio.statemachine.IOState; import org.limewire.nio.statemachine.IOStateMachine; import org.limewire.nio.statemachine.IOStateObserver; import com.limegroup.gnutella.Constants; public class AsyncOutgoingHandshaker implements Handshaker, IOStateObserver { private static final Log LOG = LogFactory.getLog(AsyncOutgoingHandshaker.class); private final HandshakeSupport support; private final IOStateMachine shaker; private final Socket socket; private final HandshakeObserver observer; public AsyncOutgoingHandshaker(Properties requestHeaders, HandshakeResponder responder, Socket socket, HandshakeObserver observer) { this.socket = socket; this.support = new HandshakeSupport(socket.getInetAddress().getHostAddress()); List<IOState> states = HandshakeState.getOutgoingHandshakeStates(support, requestHeaders, responder); this.shaker = new IOStateMachine(this, states); this.observer = observer; } public void shake() throws SocketException { socket.setSoTimeout(Constants.TIMEOUT); ((NIOMultiplexor)socket).setReadObserver(shaker); ((NIOMultiplexor)socket).setWriteObserver(shaker); } public HandshakeResponse getWrittenHeaders() { return support.getWrittenHandshakeResponse(); } public HandshakeResponse getReadHeaders() { return support.getReadHandshakeResponse(); } public void handleStatesFinished() { if(LOG.isDebugEnabled()) { LOG.debug("Finished handshake with " + socket.getInetAddress().getHostAddress() + ":" + socket.getPort()); } observer.handleHandshakeFinished(this); } public void handleIOException(IOException iox) { if(LOG.isDebugEnabled()) { LOG.debug(iox + ", " + socket.getInetAddress().getHostAddress() + ":" + socket.getPort()); } if(iox instanceof NoGnutellaOkException) { NoGnutellaOkException ngok = (NoGnutellaOkException)iox; observer.handleNoGnutellaOk(ngok.getCode(), ngok.getMessage()); } else { observer.handleBadHandshake(); } } public void shutdown() { if(LOG.isDebugEnabled()) { LOG.debug("Shutting down handshake with " + socket.getInetAddress().getHostAddress() + ":" + socket.getPort()); } observer.shutdown(); } }