001: package pygmy.core;
002:
003: import javax.net.ServerSocketFactory;
004: import java.net.ServerSocket;
005: import java.net.Socket;
006: import java.net.InetAddress;
007: import java.io.IOException;
008: import java.util.Properties;
009: import java.util.logging.Logger;
010: import java.util.logging.Level;
011:
012: /**
013: * This EndPoint provides normal sockets for the http protocol. It can be sublasses and overriden for protocols other
014: * than http.
015: *
016: * <table class="inner">
017: * <tr class="header"><td>Parameter Name</td><td>Explanation</td><td>Default Value</td><td>Required</td></tr>
018: * <tr class="row"><td>port</td><td>The port the socket should listen on.</td><td>80</td><td>No</td></tr>
019: * <tr class="altrow"><td>host</td><td>The ip or dns of the host adapter this socket should bind to.</td><td>None</td><td>No</td></tr>
020: * <tr class="row"><td>resolveHostName</td><td>If the server should do a reverse DNS on the connections so the logs will show the DNS name of the client.</td><td>false</td><td>No</td></tr>
021: * </table>
022: */
023: public class ServerSocketEndPoint implements EndPoint, Runnable {
024:
025: private static final Logger log = Logger
026: .getLogger(ServerSocketEndPoint.class.getName());
027:
028: private static final ConfigOption PORT_OPTION = new ConfigOption(
029: "port", "80", "HTTP server port.");
030: private static final ConfigOption RESOLVE_HOSTNAME_OPTION = new ConfigOption(
031: "resolveHostName", "false", "Resolve host names");
032:
033: protected ServerSocketFactory factory;
034: protected ServerSocket socket;
035: protected Server server;
036: protected String endpointName;
037: protected boolean resolveHostName;
038:
039: public ServerSocketEndPoint() {
040: factory = ServerSocketFactory.getDefault();
041: }
042:
043: public void initialize(String name, Server server)
044: throws IOException {
045: this .endpointName = name;
046: this .server = server;
047: resolveHostName = RESOLVE_HOSTNAME_OPTION.getBoolean(server,
048: endpointName).booleanValue();
049: }
050:
051: public String getName() {
052: return endpointName;
053: }
054:
055: protected ServerSocket createSocket(int port) throws IOException {
056: ServerSocket socket = factory.createServerSocket(port);
057: return socket;
058: }
059:
060: public void start() {
061: try {
062: this .socket = createSocket(PORT_OPTION.getInteger(server,
063: endpointName).intValue());
064: log.log(Level.INFO, "Socket listening on port "
065: + socket.getLocalPort());
066: Thread thread = new Thread(this , endpointName + "["
067: + socket.getLocalPort() + "] ServerSocketEndPoint");
068: thread.setDaemon(true);
069: thread.start();
070: } catch (IOException e) {
071: log.log(Level.SEVERE, "IOException ignored", e);
072: } catch (NumberFormatException e) {
073: log.log(Level.SEVERE, "NumberFormatException ignored", e);
074: }
075: }
076:
077: public void run() {
078: try {
079: while (true) {
080: Socket client = socket.accept();
081: Properties config = new ChainableProperties(server
082: .getConfig());
083: Runnable runnable = createRunnable(client, config);
084: if (resolveHostName) {
085: // after resolving, the host name appears Socket.toString.
086: InetAddress clientAddress = client.getInetAddress();
087: clientAddress.getHostName();
088: }
089: if (log.isLoggable(Level.INFO)) {
090: log.info("Connection from: " + client.toString());
091: }
092: server.post(runnable);
093: }
094: } catch (IOException e) {
095: log.log(Level.SEVERE, "IOException ignored", e);
096: }
097: }
098:
099: private String getHost(Socket socket) {
100: String host = server.getProperty("host");
101: if (host != null)
102: return host;
103: return socket.getLocalAddress().getHostName();
104: }
105:
106: protected String getProtocol() {
107: return "http";
108: }
109:
110: protected Runnable createRunnable(Socket client, Properties config)
111: throws IOException {
112: ConnectionRunnable runnable = new ConnectionRunnable(server,
113: getProtocol(), client, config);
114: return runnable;
115: }
116:
117: public void shutdown(Server server) {
118: if (socket != null) {
119: try {
120: socket.close();
121: } catch (IOException e) {
122: e.printStackTrace();
123: }
124: }
125: }
126: }
|