From b086f57f56bf0eb9dab9cf321a0f69aaaae84347 Mon Sep 17 00:00:00 2001 From: Andrew Branson Date: Wed, 30 May 2012 08:37:45 +0200 Subject: Initial Maven Conversion --- .../c2kernel/utils/server/HTTPRequestHandler.java | 160 +++++++++++++++++++++ .../c2kernel/utils/server/SimpleTCPIPServer.java | 109 ++++++++++++++ .../com/c2kernel/utils/server/SocketHandler.java | 15 ++ .../com/c2kernel/utils/server/UDPListener.java | 54 +++++++ 4 files changed, 338 insertions(+) create mode 100644 src/main/java/com/c2kernel/utils/server/HTTPRequestHandler.java create mode 100644 src/main/java/com/c2kernel/utils/server/SimpleTCPIPServer.java create mode 100644 src/main/java/com/c2kernel/utils/server/SocketHandler.java create mode 100644 src/main/java/com/c2kernel/utils/server/UDPListener.java (limited to 'src/main/java/com/c2kernel/utils/server') diff --git a/src/main/java/com/c2kernel/utils/server/HTTPRequestHandler.java b/src/main/java/com/c2kernel/utils/server/HTTPRequestHandler.java new file mode 100644 index 0000000..886ae9f --- /dev/null +++ b/src/main/java/com/c2kernel/utils/server/HTTPRequestHandler.java @@ -0,0 +1,160 @@ +package com.c2kernel.utils.server; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.Socket; +import java.util.Date; +import java.util.HashMap; +import java.util.NoSuchElementException; +import java.util.StringTokenizer; + +import com.c2kernel.utils.Logger; + +public class HTTPRequestHandler implements SocketHandler { + + protected HashMap headers = new HashMap(); + protected String method; + protected String resource; + protected String version; + protected String returnMIME; + protected String statusCode; + protected String postData; + protected final static String CRLF = "\r\n"; + protected BufferedReader request; + protected Socket currentSocket = null; + + public HTTPRequestHandler() { } + + @Override + public String getName() { + return "HTTP Server"; + } + + @Override + public boolean isBusy() { + return (currentSocket!=null); + } + + @Override + public void setSocket(Socket newSocket) { + currentSocket = newSocket; + } + + @Override + public void shutdown() { + try { + if (currentSocket != null) currentSocket.close(); + } catch (IOException e) { + Logger.error("Error shutting down HTTP connection"); + } + currentSocket = null; + } + + @Override + public void run() { + Thread.currentThread().setName("HTTP Request Handler"); + try { + request = new BufferedReader(new InputStreamReader(currentSocket.getInputStream())); + // parse the request + boolean firstLine = true; + String headerLine; + do { + headerLine = request.readLine(); + if (headerLine == null) + throw new IOException("Disconnected"); + if (firstLine) { // request line + StringTokenizer params = new StringTokenizer(headerLine); + try { + method = params.nextToken(); + resource = params.nextToken(); + version = params.nextToken(); + } catch (NoSuchElementException ex1) { } // incomplete request line - doesn't matter + firstLine = false; + } + else { // headers + int split = headerLine.indexOf(": "); + if (split >= 0) + headers.put( + headerLine.substring(0, split), + headerLine.substring(split+2) + ); + } + } while (!headerLine.equals(CRLF) && !headerLine.equals("")); + + String response = null; + + try { + + if (headers.containsKey("Content-length")) { // read POST data + StringBuffer postBuffer = new StringBuffer(); + int received = 0; int length = Integer.parseInt(headers.get("Content-length")); + try { + while (received < length) { + String postLine = request.readLine(); + postBuffer.append(postLine); + received+=postLine.length(); + } + } catch (IOException ex) { + Logger.error("Error reading post data. "+received+" bytes of "+length+" received. ("+(received*100.0/length)+"%"); + Logger.error(ex); + throw ex; + } + } + // Got the params, generate response + + returnMIME = "text/xml"; + statusCode = "200 OK"; + + response = processRequest(); + } catch (Exception ex3) { + response = error("500 Server Error", ex3.getClass().getName()+"
"+ex3.getMessage()); + } + System.out.println(new Date().toString()+" "+currentSocket.getInetAddress()+" "+method+" "+resource+" "+statusCode); + + OutputStream output = currentSocket.getOutputStream(); + + statusCode = "HTTP/1.0 "+statusCode+CRLF; + output.write(statusCode.getBytes()); + + returnMIME = "Content-type: "+returnMIME+CRLF; + output.write(returnMIME.getBytes()); + + String contentLength = "Content-Length: "+response.length()+CRLF; + output.write(contentLength.getBytes()); + + // Possible: last mod? + // end of headers + output.write(CRLF.getBytes()); + + // write the content + output.write(response.getBytes()); + request.close(); + output.close(); + currentSocket.close(); + } catch (IOException ex2) { + Logger.error(ex2); + } // aborted connection probably + currentSocket = null; + } + + /* This is a dummy method that doesn't support anything. + * Override it. + */ + + public String processRequest() { + return error("501 Not Implemented", "The method "+method+" you have requested is not supported by this server."); + } + + public String error(String code, String desc) { + statusCode = code; + returnMIME = "text/html"; + return ("" + + ""+code+"" + + "

"+code+"

" + + "

"+desc+ + "


Cristal Item HTTP server"); + } +} + diff --git a/src/main/java/com/c2kernel/utils/server/SimpleTCPIPServer.java b/src/main/java/com/c2kernel/utils/server/SimpleTCPIPServer.java new file mode 100644 index 0000000..930fcee --- /dev/null +++ b/src/main/java/com/c2kernel/utils/server/SimpleTCPIPServer.java @@ -0,0 +1,109 @@ +package com.c2kernel.utils.server; + +import java.io.InterruptedIOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.ArrayList; +import java.util.ListIterator; +import java.util.NoSuchElementException; + +import com.c2kernel.utils.Logger; + + +public class SimpleTCPIPServer implements Runnable +{ + int port = 0; + int maxConn = 10; + Thread listener = null; + Class handlerClass = null; + ServerSocket serverSocket = null; + boolean keepListening = true; + ArrayList currentHandlers = new ArrayList(); + static short noServers = 0; + + public SimpleTCPIPServer(int port, Class handlerClass, int maxConnections) + { + this.port = port; + this.handlerClass = handlerClass; + this.maxConn = maxConnections; + noServers++; + } + + public void startListening() + { + if(listener != null) return; + keepListening = true; + + listener = new Thread(this); + listener.start(); + } + + public void stopListening() + { + Logger.msg("SimpleTCPIPServer: Closing server for " + handlerClass.getName() +" on port "+ port); + keepListening = false; + for (SocketHandler thisHandler : currentHandlers) { + thisHandler.shutdown(); + } + } + + @Override + public void run() + { + Thread.currentThread().setName("TCP/IP Server for "+handlerClass.getName()); + Socket connectionSocket = null; + + try { + serverSocket = new ServerSocket(port); + if (port == 0) + port = serverSocket.getLocalPort(); + Logger.msg("SimpleTCPIPServer: Created server for " + handlerClass.getName()+" on port "+port); + serverSocket.setSoTimeout(500); + SocketHandler freeHandler = null; + while(keepListening) { + if (freeHandler == null || freeHandler.isBusy()) { + ListIterator i = currentHandlers.listIterator(); + try { + do { + freeHandler = i.next(); + } while (freeHandler.isBusy()); + } catch (NoSuchElementException e) { + // create new one + if (currentHandlers.size() < maxConn) { + freeHandler = (SocketHandler)handlerClass.newInstance(); + currentHandlers.add(freeHandler); + } + else { // max handlers are created. wait for a while, then look again + Logger.warning("No free handlers left for "+handlerClass.getName()+" on port "+ port + "!"); + Thread.sleep(2000); + continue; + } + } + } + try { + connectionSocket = serverSocket.accept(); + if (keepListening) { + Logger.msg("SimpleTCPIPServer: Connection to "+freeHandler.getName()+" from "+ + connectionSocket.getInetAddress()); + freeHandler.setSocket(connectionSocket); + new Thread(freeHandler).start(); + } + } catch (InterruptedIOException ex1) { }// timeout just to check if we've been told to die + + } + serverSocket.close(); + Logger.msg("SimpleTCPIPServer: Server closed for " + handlerClass.getName() +" on port "+ port); + } catch(Exception ex) { + Logger.error(ex); + Logger.error("SimpleTCPIPServer.run(): Fatal Error. Listener for '"+handlerClass.getName()+"' will stop."); + listener = null; --noServers; + return; + } + listener = null; + Logger.msg("SimpleTCPIPServer - Servers still running: "+--noServers); + } + + public int getPort() { + return port; + } +} diff --git a/src/main/java/com/c2kernel/utils/server/SocketHandler.java b/src/main/java/com/c2kernel/utils/server/SocketHandler.java new file mode 100644 index 0000000..8d37714 --- /dev/null +++ b/src/main/java/com/c2kernel/utils/server/SocketHandler.java @@ -0,0 +1,15 @@ +package com.c2kernel.utils.server; + +import java.net.Socket; + +public interface SocketHandler extends Runnable { + + public String getName(); + + public boolean isBusy(); + + public void setSocket(Socket newSocket); + + public void shutdown(); +} + diff --git a/src/main/java/com/c2kernel/utils/server/UDPListener.java b/src/main/java/com/c2kernel/utils/server/UDPListener.java new file mode 100644 index 0000000..3b1fc9d --- /dev/null +++ b/src/main/java/com/c2kernel/utils/server/UDPListener.java @@ -0,0 +1,54 @@ +package com.c2kernel.utils.server; + +import java.io.IOException; +import java.io.InterruptedIOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; + +import com.c2kernel.common.InvalidDataException; +import com.c2kernel.utils.Logger; + +/************************************************************************** + * + * $Revision: 1.2 $ + * $Date: 2004/02/06 14:50:43 $ + * + * Copyright (C) 2003 CERN - European Organization for Nuclear Research + * All rights reserved. + **************************************************************************/ + +public abstract class UDPListener extends Thread { + + private boolean active = true; + protected DatagramSocket socket; + + public UDPListener() { + super(); + } + + @Override + public void run() { + Thread.currentThread().setName("UDP Server"); + byte[] buffer = new byte[255]; + DatagramPacket newPacket = new DatagramPacket(buffer, buffer.length); + while (active) { + try { + socket.receive(newPacket); + processPacket(newPacket); + } catch (InterruptedIOException e) { // ignore timeout + } catch (IOException e) { + Logger.error("Error receiving proxy packet:"); + Logger.error(e); + } catch (InvalidDataException e) { + Logger.error(e); + } + } + socket.close(); + } + + protected abstract void processPacket(DatagramPacket packet) throws InvalidDataException; + + public void shutdown() { + active = false; + } +} -- cgit v1.2.3