//Dan Goldberg import java.net.*; import java.lang.*; import java.text.*; import java.util.*; import java.io.*; public class working_server extends Thread { public Properties _serverConfig; public Properties _mimeTypes; public Hashtable ht = new Hashtable(); public Hashtable _mt; public Hashtable headerValues = new Hashtable(); public Hashtable attrValues = new Hashtable(); public String [] headerArray; public String [] env; public Socket _s; public double corruptionProbability; public int packetSize; public ServerSocket mainSocket; public Socket serviceSocket; public BufferedReader dataFromClient; public OutputStream dataToClient; public String fileName; public String serverData; public String clientData; public Random randomGenerator; String methodType = ""; String http = ""; String domain = ""; String cgivars = ""; String protocol = ""; String httpVerSt = ""; String httpVer = "0.0"; double httpVersion = 0.0; String filetype = ""; String filepath = ""; String serverRoot = ""; boolean send404 = false; String temp = ""; String host = ""; String ques = ""; String filenm = ""; String filename = ""; String url = ""; String headers = ""; String ctype = ""; int quesE = 0; int numEnvVars = 0; boolean cnt = true; boolean validMethod = false; boolean docDefined = false; boolean sent = false; boolean body = false; public working_server(Socket s, Properties serverConfig, Properties mimeTypes, Hashtable mt) { _s = s; _serverConfig = serverConfig; _mimeTypes = mimeTypes; _mt = mt; } public void run() { System.out.println("\n\n\n\nSession Started\n----------------------"); try { //Begin reading request dataFromClient = new BufferedReader(new InputStreamReader(_s.getInputStream())); dataToClient = _s.getOutputStream(); File mtFile = new File(_serverConfig.getProperty("server.root") + "mime.types"); BufferedReader br = new BufferedReader(new FileReader(mtFile)); String line = ""; while ((line = br.readLine()) != null) { StringTokenizer MTtype = new StringTokenizer(line,"="); _mt.put(MTtype.nextToken(),MTtype.nextToken()); } parseRequest(); // handle request sendResponse(); // if all else fails send a 500 error /* byte [] temp; String st; st = dataFromClient.readLine(); System.out.println(st); st = st+"\r\n"; temp = st.getBytes(); dataToClient.write(temp); st = ""; */ } catch (FileNotFoundException e) {} catch (IOException e) {} catch (InterruptedException e) {} catch (NullPointerException e) {} } public void parseRequest () throws FileNotFoundException, IOException, InterruptedException { //method which parses the incoming request line by line String thisline = dataFromClient.readLine(); System.out.println(thisline); StringTokenizer line = new StringTokenizer(thisline, "\r"); Vector tempV = new Vector(); String rqline = ""; System.out.println("Parsing Request"); while(!thisline.equals("")){ tempV.addElement(thisline); thisline = dataFromClient.readLine(); } parseHeaders(tempV); // Parse extra headers like refferer //begin parsing the request line rqline = (String) tempV.elementAt(0); StringTokenizer st = new StringTokenizer(rqline, " "); String [] request = new String[255]; int count = 0; // will get the method type, file location, and http Ver while(st.hasMoreTokens()) { request[count] = st.nextToken(); count++; } if (count == 1){ // Bad request httpVer = "1.0"; sendError(400, "Bad Request -- only 1 arg"); } else if (count == 2){ // No protocol 0.9 is assumed httpVer = "0.9"; methodType = request[0]; checkMethod(methodType); url = request[1]; checkUrl(url); } else if (count == 3){ //Valid request so far httpVerSt = request[2]; checkHttpVer(request); methodType = request[0]; checkMethod(methodType); url = request[1]; checkUrl(url); } else { // Bad request httpVer = "1.0"; sendError(400, "Bad Request -- more than 3 args"); } } public void checkMethod(String meth) throws IOException{ //Method which validates the users method meth = meth.toUpperCase(); methodType = meth; if (((meth.equals("GET")) || (meth.equals("POST")) || (meth.equals("HEAD")))){ validMethod = true; } else if (((meth.equals("OPTIONS")) || (meth.equals("PUT")) || (meth.equals("DELETE")) || (meth.equals("TRACE")))){ validMethod = false; sendError(501, "Method Not Implemented"); } else{ validMethod = false; sendError (400, "Bad Request -- Uknown Method"); httpVer = "1.0"; } } public void checkUrl(String newUrl) throws FileNotFoundException, IOException, InterruptedException{ //method which parses and checks the URL portion ofthe request line System.out.println("Checking url"); if (url.equals("/")){ //ge the default file System.out.println("There's nothing but a /"); filename = _serverConfig.getProperty("default.doc"); serverRoot = _serverConfig.getProperty("server.root"); filepath = serverRoot + _serverConfig.getProperty("doc.root"); filetype = _serverConfig.getProperty("default.type"); File defFile = new File(filepath,filename); getCT(filename); sendFile(defFile); } if ((methodType.equals("GET")) || (methodType.equals("POST")) || (methodType.equals("HEAD"))){ { if (url.startsWith("/")) { StringTokenizer rqline = new StringTokenizer(url,"/"); while (rqline.hasMoreTokens() && cnt) //llop through the URL { ques = rqline.nextToken(); quesE = ques.indexOf("?"); //if ((quesE != -1) || (url.regionMatches(true,0,"cgi",0,url.length()))) if ((quesE != -1) || (ques.indexOf(".cgi")!=-1)) { //We've got a cgi to proccess System.out.println("There's a ? mark or a cgi"); if (quesE != -1){ StringTokenizer splitQ = new StringTokenizer(ques,"?"); filenm = splitQ.nextToken(); cgivars = splitQ.nextToken(); handleCGI(filenm, cgivars); } else{ //We've got a cgi with out a ? mark System.out.println("gotcha"); filenm = ques; handleCGI(filenm, ""); } } else if ((quesE == -1)) { //incoming URL request has no cgi in it or ? -- its a static file System.out.println("There's no ? mark -- not cgi"); System.out.println("Anything but POST file: "); temp = temp + ques; filepath = _serverConfig.getProperty("server.root") + _serverConfig.getProperty("doc.root"); File staticFile = new File(filepath,temp); if (staticFile.isDirectory()) { //loop through the directories of the request temp = temp + "/"; if(!rqline.hasMoreTokens()){ File defStaticFile = new File(_serverConfig.getProperty("server.root")+_serverConfig.getProperty("doc.root")+"/"+temp, _serverConfig.getProperty("default.doc")); getCT(_serverConfig.getProperty("default.doc")); sendFile(defStaticFile); } } else if ((staticFile.isFile()) && staticFile.canRead()) { //Its a valid file to read // System.out.println("staticfile = " +staticFile+ "\n"); filenm = ques; // temp = temp + filenm; cnt = false; //System.out.println("filenm = " + filenm + "\n" ); getCT(filenm); sendFile(staticFile); } else if (!staticFile.isFile()){ sendError(404, "File Not Found"); } else if (!staticFile.canRead()){ sendError(403, "Forbidden -- File not readable"); } else { System.out.println("Not found: " + filepath); sendError(404, "File not found"); } } } } } } } public void checkHttpVer(String [] rq) throws IOException{ //Method which tests the HTTP Protocol portion of the request line rq[2] = rq[2].toUpperCase(); if (rq[2] == null) { httpVer = "0.9"; } else if (rq[2].compareTo("HTTP/1.0") == 0) { httpVer = "1.0"; } else if ((rq[2].startsWith("HTTP/") && (!(rq[2].compareTo("HTTP/1.0") == 0)) && (!(rq[2].compareTo("HTTP/0.9") == 0)))) { httpVer = "1.0"; } else { httpVer = "1.0"; sendError(400,"Bad HTTP Specification"); } } public void parseHeaders(Vector v) { //Method which handles and parses the additional headers in the request and stores them in Env Variables System.out.println("Parsing Headers"); try{ if(v.isEmpty()){ sendError(400, "Bad Request -- nothing"); } } catch(IOException e){ System.err.println("IOException"); System.exit(-1); } int vsize = v.size(); int c; int b; String name = ""; String value = ""; String temp = ""; StringTokenizer tp; if(vsize<=1){ numEnvVars = 2; return; } else{ //Test headers for validity numEnvVars = 2; for (int j=1; j

Error: 500 Internal Server Error

"; st = "HTTP/1.0 500 Internal Server Error\r\n"; st = st + "Connection: Close \r\n"; st = st + "Content-length: "+ err.length() + "\r\n"; st = st + "Content-type: text/html \r\n"; st = st + err; temp = st.getBytes(); dataToClient.write(temp); st = ""; _s.close(); this.stop(); } sent = true; } public void sendError(int errNum, String errDes) throws IOException{ //method which sends detailed error message System.out.println("Into SendError"); if(!sent){ byte [] temp; String st; String err = "Error " + errNum+ ": "+ errDes+" "; err = err +"

Error: " +errNum +" " + errDes + "

"; st = "HTTP/"+httpVer+" "+errNum+" "+errDes+"\r\n"; st = st + "Connection: Close \r\n"; st = st + "Content-length: "+ err.length() + "\r\n"; st = st + "Content-type: text/html \r\n"; st = st + err; temp = st.getBytes(); dataToClient.write(temp); st = ""; _s.close(); this.stop(); } sent = true; } public void getCT(String rqFile){ //method which gets the content type of files System.out.print("Into Content Type \n"); StringTokenizer st = new StringTokenizer(rqFile,"."); String fname = st.nextToken(); System.out.print("Fname: " + fname + " \n"); String ext = st.nextToken(); System.out.print("Ext: " + ext + " \n"); ctype = (String) _mt.get(ext); } public SimpleDateFormat getDate(){ //method which gets the time String dateFormatString = "EEE, dd MMM yyyy, kk:mm:ss z"; SimpleDateFormat sdf = new SimpleDateFormat(dateFormatString); sdf.setTimeZone(TimeZone.getTimeZone("GMT")); return sdf; } public static void main (String [] args) throws FileNotFoundException, IOException, InterruptedException, NoSuchMethodError { Properties serverConfig = new Properties(); Properties mimeTypes = new Properties(); Hashtable mt = new Hashtable(); // new File(".").getAbsolutePath(); serverConfig.load(new FileInputStream(new File(".").getAbsolutePath()+"/srm.conf")); mimeTypes.load(new FileInputStream(new File(".").getAbsolutePath()+"/mime.types")); int localport = -1; boolean error = false; int defport = new Integer(serverConfig.getProperty("port")).intValue(); String usage = "usage: java working_server [-p]\noptions:\n[-p port number] the port to run on (default port: " + defport +")"; try{ for (int i=0; i=args.length){ System.err.println(usage); System.exit(1); } localport = new Integer(args[i]).intValue(); // localport = parselocalport.parseInt(args[i], 10); } else{ System.err.println(usage); System.exit(1); } } } catch(NumberFormatException e){ System.err.println("Error: " + e.getMessage() + "\n"); System.exit(1); } /* if(localport <= 0){ System.err.println("Error: Invalid Local Port Specification " + "\n"); error = true; } } if (args.length > 1){ System.err.println("Usage: server \n or server (default port used)"); } if(error) System.exit(-1); if (localport == -1){ localport = new Integer(serverConfig.getProperty("port")).intValue(); } */ if(localport==-1) localport=defport; System.out.println("Starting server on port " + localport); ServerSocket ss = new ServerSocket(localport); while(true) { //loop forever Socket s = ss.accept(); //Blocks waiting for a new connection working_server serv = new working_server(s, serverConfig, mimeTypes, mt); //Create a new child process serv.start(); //Start the child process } } }