Eliza.java

From Chaos Communication Camp 2007

Jump to: navigation, search
package ccc.camp.chat;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Eliza extends HttpServlet {
	
	public static final String webcamUrl = "http://81.163.48.165/~fh/images/dbadatccc.jpg";
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	static List<Message> messages = new ArrayList<Message>();
	static Map<String,Date> online = new HashMap<String, Date>();

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		
		String pathInfo = req.getPathInfo();
		
		resp.setCharacterEncoding("utf-8");
		resp.setContentType("text/html");
		
		if (pathInfo.startsWith("/messages")) {
			printProtocol(req, resp);
			System.err.print("request: " + pathInfo);
			System.err.print("\n");
			return;
		}
		
		if (pathInfo.startsWith("/lastmessages")) {
			
			trackOnlineUsers(req);
			printLastMessagesTable(req, resp.getWriter());
			return;
		}
		PrintWriter writer = resp.getWriter();
		if (pathInfo.startsWith("/users")) {
			writer.println(online.size());
			return;
		}
		
		writer.print("<html><body onload=\"document.getElementById('msg').focus()\">\n");
		writer.print("<h1>SimpleCCCCChatServer</h1>");
		writer.print("<div  style=\"float:left\">");
		writer.print("<form>");
		writer.print("enter your message: ");
		writer.print("<input type=\"text\" size=\"80\" id=\"msg\" name=\"msg\"/>");
		writer.print("");
		writer.print("");
		writer.print("");
		writer.print("");
		
		
		Map<String, String[]> params = req.getParameterMap();
		for (String param : params.keySet()) {
			StringBuilder msg = new StringBuilder(param);
			msg.append(": ");
			String msgbody = params.get(param)[0];
			msg.append(msgbody);
			addMsgToHistory(req, msgbody);
			System.err.print("\tmsg: " + msgbody + "\n");
		}
		writer.println("</form>");
		writer.print("<div style=\"width:500px; text-align:right\"><span id=\"online\">");
		writer.print(online.size());
		writer.print("</span> user(s) online.</div>");
		writer.print("<div id=\"lastmsgs\">");
		printLastMessagesTable(req, writer);
		writer.print("</div>");
		writer.print("<a href=\"/messages\">see all messages...</a></div><div style=\"float:left\"><br><br>see where this server is located:<br><br><img id=\"campcam\" src=\"");
		writer.print(webcamUrl);
		writer.print("\"><div>");
		printImgUpdateScript(writer);
		writer.print("</body></html>\n");
		
		writeProtocol();
	}

	private void trackOnlineUsers(HttpServletRequest req) {
		Date now = new Date();
		boolean newIp = true; 
		String remoteHost = req.getRemoteHost();
		for(String ip : online.keySet()) {
			Date d = online.get(ip);
			if (now.getTime() - d.getTime() > 5 * 60 * 1000){ // 5 minutes
				online.remove(ip);
				System.err.print("offline: " + ip);
				System.err.print("\n");
			}
			if(ip.equals(remoteHost)){
				online.put(ip, now);
				newIp = false;
				System.err.print("updated: " + remoteHost);
				System.err.print("\n");
			}
		}
		if(newIp) {
			System.err.print("new: " + remoteHost);
			System.err.print("\n");
			online.put(remoteHost, now);
		}
		
	}

	private synchronized void writeProtocol() throws IOException, FileNotFoundException {
		File saveProtocolFile = new File("/tmp/chatprotocol.serialized");
		ObjectOutputStream ostream = new ObjectOutputStream(new FileOutputStream(saveProtocolFile));
		ostream.writeObject(messages);
		ostream.close();
	}

	private synchronized void addMsgToHistory(HttpServletRequest req, String msgbody) {
		int msize = messages.size();
		if(msize>0){
			Message last = messages.get(msize-1);
			if(msgbody.equals(last.msg)){
				// avoid double msg on reload
				return;
			}
		}
		messages.add(new Message(req.getRemoteHost(), new Date(), msgbody));
	}

	private void printLastMessagesTable(HttpServletRequest req,
			PrintWriter writer) {
		if (messages.size() > 0) {
			writer.print("<table>");
			for(int i=messages.size() - 1; i>=0 && i>messages.size()-8; i--) {
				writer.println("<tr><td>");
				Message msg = messages.get(i);
				writer.print(msg.ip(req));
				writer.print("</td><td>answered at</td><td>");
				writer.print(msg.date());
				writer.print(":</td><td><b>");
				writer.write(msg.msgFiltered());
				writer.print("</b></td></tr>");
			}
			writer.print("</table>");
		}
	}

	private void printProtocol(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		
		PrintWriter writer = resp.getWriter();
		writer.print("<html><body><h1>SimpleCCCCChatServer - The whole story</h1>");
		writer.print("<div style=\"float:left\">\n");
		
		for (int i=messages.size()-1; i>=0; i--) {
			Message msg = messages.get(i);
			writer.print(msg.out(req));
			writer.print("<br/>\n");
		}
		writer.print("</div><div style=\"margin:10px; float:left\">see where this server is located:<br><br><img id=\"webcam\" src=\"");
		writer.print(webcamUrl);
		writer.print("\"><div>");
		printImgUpdateScript(writer);
		writer.print("</body></html>\n");
	}

	private void printImgUpdateScript(PrintWriter writer) {
		writer.println("<script>");
		writer.println("var http_request_msgs = false;");
		writer.println("var http_request_users = false;");
		writer.println("function loadMessages(){");
		writer.println("http_request_msgs=null");
		// code for Mozilla, etc.
		writer.println("if (window.XMLHttpRequest){");
		writer.println("  http_request_msgs=new XMLHttpRequest()");
		writer.println("  } else if(window.ActiveXObject){");
		// code for IE
		writer.println("  http_request_msgs=new ActiveXObject(\"Microsoft.XMLHTTP\")");
		writer.println("  }");
		writer.println("if (http_request_msgs!=null){");
		writer.println("  http_request_msgs.onreadystatechange=state_Change1");
		writer.println("  var jetzt = new Date();\n var delay=3000;\n");
		writer.println("  http_request_msgs.open(\"GET\",'/lastmessages?' + jetzt.getTime(),true)");
		writer.println("  http_request_msgs.send(null)");
		writer.println("}");
		writer.println("}");
		writer.println("function state_Change1(){");
		writer.println("  if (http_request_msgs.readyState == 4) {");
		writer.println("    var table=document.getElementById(\"lastmsgs\")");
		writer.println("    table.innerHTML = http_request_msgs.responseText");
		writer.println("  }");
		writer.println("}");
		writer.println("function loadUsers(){");
		writer.println("http_request_users=null");
		// code for Mozilla, etc.
		writer.println("if (window.XMLHttpRequest){");
		writer.println("  http_request_users=new XMLHttpRequest()");
		writer.println("  } else if(window.ActiveXObject){");
		// code for IE
		writer.println("  http_request_users=new ActiveXObject(\"Microsoft.XMLHTTP\")");
		writer.println("  }");
		writer.println("if (http_request_users!=null){");
		writer.println("  http_request_users.onreadystatechange=state_Change2");
		writer.println("  var jetzt = new Date();\n var delay=3000;\n");
		writer.println("  http_request_users.open(\"GET\",'/users?' + jetzt.getTime(),true)");
		writer.println("  http_request_users.send(null)");
		writer.println("}");
		writer.println("}");
		writer.println("function state_Change2(){");
		writer.println("  if (http_request_msgs.readyState == 4) {");
		writer.println("    var users=document.getElementById(\"online\")");
		writer.println("    users.innerHTML = http_request_users.responseText");
		writer.println("  }");
		writer.println("}");
		writer.println("function update(){");
		writer.println("var jetzt = new Date();\n var delay=3000;\n");
		writer.println("loadMessages();loadUsers();document.getElementById(\"campcam\").src =\"http://81.163.48.165/~fh/images/dbadatccc.jpg?\" + jetzt.getTime();");
		writer.println("setTimeout(\"update()\",delay)};");
		writer.println("update()");
		writer.println("</script>");
	}
		
	private class Message implements Serializable {
		
		/**
		 * 
		 */
		private static final long serialVersionUID = 7916883126928225837L;
		private String ip;
		private Date date;
		private String msg;
		public Message(String ip, Date date, String msg) {
			super();
			this.ip = ip;
			this.date = date;
			this.msg = msg;
		}
		
		public String out(HttpServletRequest req) {
			StringBuilder s = new StringBuilder(date());
			s.append(" (");
			s.append(ip(req));
			s.append("): ");
			s.append(msgFiltered());
			return s.toString();
		}
		
		public String date() {
			DateFormat tf = new SimpleDateFormat("hh:mm");
			return tf.format(date);
		}
		
		public String ip(HttpServletRequest req) {
			return req.getRemoteHost().equals(ip) ? "You" : ip;
		}
		
		public String msgFiltered(){
			String out = msg.replaceAll("<", "<");
			out = out.replaceAll("\"", """);
			out = out.replaceAll("fuck", "f**k");
			return out;
		}
	}

	@Override
	public void init() throws ServletException {
		super.init();
		File chatProtFile = new File("/tmp/chatprotocol.serialized");
		try {
			ObjectInputStream ois = new ObjectInputStream(new FileInputStream(chatProtFile));
			messages = (List<Message>)ois.readObject();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
Personal tools
Archived page - Impressum/Datenschutz