/* Example of a REST server -- RAB 1/18 NOTE: This demo server handles HTTP requests within the main thread, but a production server should start a new thread to service each request Requires one command line arg: 1. port number to use (on this machine). */ import java.io.*; import java.net.*; import java.util.*; import java.nio.charset.*; public class ExampleRestServer { private static String DEBUG = "DEVEL "; static final int MAXBUFF = 100000; static boolean contin = true; // continue with main loop? static ServerSocket servSock = null; public static void main(String[] args) { int port = -1; final String prefix = new String("ExampleRestServer: "); // define API handlers ExampleRestModel model = new ExampleRestModel(); if (DEBUG != null) { System.out.println(DEBUG + "model handler keys: " + model.getHandlerKeys()); System.out.println(DEBUG + "model handler values: " + model.getHandlerValues()); } // define and start a thread to process commands from standard input, // including EXIT to shut down this server Thread commandThread = getCommandThread(prefix + "CMD: "); commandThread.start(); // perform server initialization try { port = Integer.parseInt(args[0]); System.out.println("Initializing for network communication... "); servSock = new ServerSocket(port); /* assert: ServerSocket successfully created */ } catch (IOException e) { System.err.println(prefix + "init failure."); System.err.println(e.getMessage()); System.exit(1); // an error exit status return; } // successful initialization /* MAIN LOOP: repeatedly receive new HTTP requests and reply to them, using a fresh Socket connection per request NOTE: In this simple demo, requests are handled in main thread, NOT a separate Worker thread. */ int failcount = 0; // number of consec failures with a client while (contin) { try { System.out.println("========================================\n" + "Waiting for an incoming connection... "); Socket inSock = servSock.accept(); byte[] inBuff = new byte[MAXBUFF]; int count; // to hold number of bytes of I/O count = inStream.read(inBuff); // successful read from socket System.out.println("Successfully received the following " + count + " bytes:"); System.out.write(inBuff, 0, count); HttpParser parser = new HttpParser(inBuff, 0, count); int code = parser.parseRequest(); if (DEBUG != null) dumpParseResults(parser); String reply; if (code != 200) reply = parser.makeReply(code); else { reply = model.handle(parser); } if (DEBUG != null) System.out.println(DEBUG + "Sending HTTP reply:\n" + reply + "\n" + DEBUG + "End of reply"); outStream.write(reply.getBytes()); System.out.println("HTTP reply message sent"); } catch (IOException e) { System.out.println(prefix + "client interaction failed."); System.out.println(e.getMessage()); } finally { inSock.close(); } public static Thread getCommandThread(String prefix) { return new Thread(new Runnable () { public void run() { System.out.println(prefix + "starting command thread"); System.out.flush(); byte [] buff = new byte[100]; int count; try { while ((count = System.in.read(buff)) >= 0) { String inLine = new String(buff, 0, count); if (inLine.trim().equals("EXIT")) { contin = false; servSock.close(); System.out.println(prefix + "command thread returning"); return; } else { System.out.println(prefix + "Unknown standard-input command."+ "Enter EXIT to quit"); } } } catch (IOException e) { System.err.println(prefix+"error reading standard input, aborting" + e.getMessage()); contin = false; return; } } }); } private static void dumpParseResults(HttpParser parser) { System.out.println(DEBUG + "getRequestURL() --> " + parser.getRequestURL()); System.out.println(DEBUG + "getURLBase() --> " + parser.getURLBase()); System.out.println(DEBUG + "getURLId() --> " + parser.getURLId()); System.out.println(DEBUG + "=== Printing headers ==="); for (Enumeration<String> e = parser.getHeaders().keys(); e.hasMoreElements(); ) { String next = e.nextElement(); System.out.println(DEBUG + next + ": " + parser.getHeader(next)); } System.out.println(DEBUG + "=== End headers ==="); System.out.println(DEBUG + "=== Printing parameters ==="); for (Enumeration<String> e = parser.getParams().keys(); e.hasMoreElements(); ) { String next = e.nextElement(); System.out.println(DEBUG + next + "=" + parser.getParam(next)); } System.out.println(DEBUG + "=== End parameters ==="); } }