/*
* ConnectionAcceptor - Accepts connections and routes them to sub-acceptors.
* Copyright (C) 2003 Mark J. Wielaard
*
* This file is part of Snark.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.klomp.snark;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Accepts connections on a TCP port and routes them to sub-acceptors.
*/
public class ConnectionAcceptor implements Runnable
{
private final ServerSocket serverSocket;
private final HttpAcceptor httpacceptor;
private final PeerAcceptor peeracceptor;
private Thread thread;
private boolean stop;
public ConnectionAcceptor (ServerSocket serverSocket,
HttpAcceptor httpacceptor, PeerAcceptor peeracceptor)
{
this.serverSocket = serverSocket;
this.httpacceptor = httpacceptor;
this.peeracceptor = peeracceptor;
stop = false;
}
public void start ()
{
thread = new Thread(this);
thread.start();
}
public void halt ()
{
stop = true;
ServerSocket ss = serverSocket;
if (ss != null) {
try {
ss.close();
} catch (IOException ioe) {
}
}
Thread t = thread;
if (t != null) {
t.interrupt();
}
}
public int getPort ()
{
return serverSocket.getLocalPort();
}
public void run ()
{
while (!stop) {
try {
final Socket socket = serverSocket.accept();
Thread t = new Thread("Connection-" + socket) {
@Override
public void run ()
{
try {
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
BufferedInputStream bis = new BufferedInputStream(
in);
BufferedOutputStream bos = new BufferedOutputStream(
out);
// See what kind of connection it is.
if (httpacceptor != null) {
byte[] scratch = new byte[4];
bis.mark(4);
int len = bis.read(scratch);
if (len != 4) {
throw new IOException(
"Need at least 4 bytes");
}
bis.reset();
if (scratch[0] == 19 && scratch[1] == 'B'
&& scratch[2] == 'i' && scratch[3] == 't') {
peeracceptor.connection(socket, bis, bos);
} else if (scratch[0] == 'G'
&& scratch[1] == 'E' && scratch[2] == 'T'
&& scratch[3] == ' ') {
httpacceptor.connection(socket, bis, bos);
}
} else {
peeracceptor.connection(socket, bis, bos);
}
} catch (IOException ioe) {
try {
socket.close();
} catch (IOException ignored) {
}
}
}
};
t.start();
} catch (IOException ioe) {
log.log(Level.SEVERE, "Error while accepting", ioe);
stop = true;
}
}
try {
serverSocket.close();
} catch (IOException ignored) {
}
}
/** The Java logger used to process our log events. */
protected static final Logger log = Logger.getLogger("org.klomp.snark.server");
}