Browse Source

Initial import of Cortex code from my cs416 class at UBC

longpull
Dan 11 years ago
commit
5ce2a651ef
  1. 399
      ConnHandler.java
  2. 88
      Cortex.java
  3. 15
      Makefile
  4. 179
      ResManager.java
  5. 6
      Runner.java
  6. 94
      TSP_map_test.js
  7. 47
      ajax.js
  8. 1973
      client.html
  9. 8
      gen-cert.sh
  10. 43
      shell.html

399
ConnHandler.java

@ -0,0 +1,399 @@
import java.applet.*;
//import java.awt.*;
import java.awt.event.*;
import javax.swing.Timer;
import java.awt.image.*;
import java.net.InetSocketAddress;
import java.net.InetAddress;
import java.lang.*;
import java.io.*;
import java.net.*;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Scanner;
import java.util.HashMap;
import javax.swing.JOptionPane.*;
import java.util.Enumeration;
import java.util.List;
import java.util.ArrayList;
class ConnHandler implements Runnable {
Socket sock;
ResManager res;
final int TYPE_GET = 0;
final int TYPE_POST = 1;
public ConnHandler(Socket s, ResManager r) {
sock = s;
res = r;
}
/* parseAjax
* Ajax content is in form of
* (key=value\n)*\n\n
* returns a string:string hashmap of key value pairs
*/
HashMap<String, String> parseAjax(BufferedReader sin) {
HashMap<String, String> req = new HashMap<String, String>();
Scanner scan = new Scanner(sin);
scan.useDelimiter("\n\n");
String all = scan.next();
req.put("req", all);
for ( String line : all.split("\n")) {
String kv[] = line.split("=");
req.put(kv[0], kv[1]);
}
return req;
}
String ajaxCall(String dest, BufferedReader sin) {
Socket client = null;
PrintWriter out = null;
BufferedReader in = null;
// Get Ajax call
Scanner scan = new Scanner(sin);
scan.useDelimiter("\n\n");
String all = scan.next();
//res.log("Sending to " + dest + ": '" + all +"'");
// clean up dest
// Connect to dest
try {
//res.alert(dest);
String[] d = dest.split(":");
//res.alert(Integer.toString( d.length));
String p = "2600";
if (d.length > 1)
p = d[1];
client = new Socket(d[0], Integer.parseInt(p));
//InetAddress addr = new InetSocketAddress("127.0.0.1");
if (!client.isConnected())
res.error("failed to connect!!!!!!!");
//"127.0.0.1", 2600); //dest, res.PORT);
//client.connect(addr, 2600);
out = new PrintWriter(client.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
} catch (Exception e) {
res.log( "ERROR> Exception in ajaxCall (Connecting): " + e.toString());
return "";
}
//res.alert("Established connection");
// HTTP / AJAX Header + call
out.print("POST / HTTP/1.1\r\n" +
"Host: " + dest + "\r\n" +
"User-Agent: Cortex\r\n" +
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" +
"Accept-Language: en-us,en;q=0.5\r\n"+
"Accept-Encoding: gzip,deflate\r\n" +
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" +
"Keep-Alive: 300\r\n" +
"Connection: keep-alive\r\n" +
"Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n" +
"Referer: http://localhost:2600/client.html\r\n" +
"Content-Length: " + (all.length()+2) + "\r\n" +
"Pragma: no-cache\r\n" +
"Cache-Control: no-cache\r\n" +
"\r\n");
out.print(all + "\n\n");
out.flush();
//res.log("sent message");
//out.close();
//res.alert("printed request, trying to read");
// Read response
String resp = "";
// read http header
//res.log("Reading resp header");
try {
String header = in.readLine();
while (header.length() >= 3) {
//res.log("header: " + header);
header = in.readLine();
}
} catch (Exception e) {
res.error("Exception in ajaxCall (reading HTTP response header): " + e.toString());
return "";
}
//res.log("Reading response body");
//res.alert("done reading resp header");
// read actual response
scan = new Scanner(in);
scan.useDelimiter("\n\n");
resp = scan.next();
//res.alert("done reading resp");
//res.log("Closing ajaxCall");
try {
in.close();
out.close();
client.close();
} catch (Exception e) {
res.error( "Exception in ajaxCall (Closing Connection): " + e.toString());
}
//res.alert("closed connections");
//res.log("ajaxCall returning response to js caller: '" + resp + "'");
return resp;
}
// Function to enumerate all IP addresses of a computer
// and then try and select the web facing one
private String getIPAddress() {
ArrayList<String> ips = new ArrayList<String>();
try {
Enumeration e = NetworkInterface.getNetworkInterfaces();
while(e.hasMoreElements()) {
NetworkInterface ni = (NetworkInterface) e.nextElement();
Enumeration e2 = ni.getInetAddresses();
InetAddress ip=null;
String istr = null;
while (e2.hasMoreElements()){
ip = (InetAddress) e2.nextElement();
istr = ip.toString();
if (istr.substring(0,1).equals("/"))
istr = istr.substring(1);
if (istr.charAt(0) >= '0' && istr.charAt(0) <= '9' && istr.indexOf(':') == -1) {
//res.log("adding: '" + istr +"'");
ips.add(istr);
}
//ip = (InetAddress) e2.nextElement();
}
/*if (ip == null)
continue;
istr = ip.toString();
if (istr.substring(0,1).equals("/"))
istr = istr.substring(1);
ips.add(istr);*/
}
} catch (Exception e) {
res.error( "Exception in ConnHandler.getIPAddress(): " + e.toString());
}
// Now we have a list of IPs associated with this machine. Lets pick the best one
if (ips.size() == 0)
return "";
else if (ips.size() == 1)
return ips.get(0);
else {
ips.remove("127.0.0.1");
/*for (int i=0; i< ips.size(); i++) {
if(ips.size() ==1)
break;
String ip = ips.get(i);
if (
*/
// Many IPs so weed out baddies
for (int i=0; i < ips.size(); i++) {
if (ips.size() == 1)
break;
String ip = ips.get(i);
// remove local private subnets
if(ip.substring(0, 7).equals("192.168")) {
ips.remove(i);
i--;
} else if (ip.substring(0, 3).equals("10.")) {
ips.remove(i);
i--;
}
}
return ips.get(0);
}
}
/* handleAjax
* handle the various ajax commands appropriately
*/
private String handleAjax(HashMap<String, String> req) {
String response = "";
String cmd = req.get("cmd");
//res.log("AJAX " + cmd);
if (cmd.equals("ping")) {
response = "pong";
//res.log("PING pong");
} else if (cmd.equals("greet")) {
response = getIPAddress() + ":" + res.PORT + " " + res.getNodeData("originURL") ;
} else if (cmd.equals("getLog")) {
ArrayList<String> l = res.getLog();
response = "";
for (int i = l.size()-1; i >= 0; i--) {
response += l.get(i) + "\n";
}
// response += " ";
} else if (cmd.equals("reloadHTML")) {
res.log("Reloading HTML from src...");
res.reloadSite();
} else if (cmd.equals("sendMsg")) {
//res.log("sendMsg: query=" + req.get("query"));
res.queueMsg(req.get("req"));
response = "received on " + res.PORT;
} else if (cmd.equals("getMsgs")) {
ArrayList<String> mq = res.getMsgs();
for(int i =0; i < mq.size(); i++) {
response += mq.get(i) + "\n\n";
}
//res.log("getMsgs: '" + response + "'");
//response = "";
} else if (cmd.equals("kill")) {
res.killSwitch = true;
} else {
response = "Unknown cmd: " + cmd;
res.log("Unknown cmd: " + cmd);
}
return response;
}
/* Handle GET requests
* A GET request is a generic browser request,
* meaning not an AJAX request, so we serve the main
* interface html file.
*/
private byte[] handleGet(String req) {
//javax.swing.JOptionPane.showMessageDialog(null, "GET: " + req);
int end = req.indexOf(' ');
req = req.substring(1, end);
//res.alert("'" + req + "'");
if (req.equals(""))
req = "shell.html";
byte[] r = res.getSite(req);
if (r == null) {
//javax.swing.JOptionPane.showMessageDialog(null, "Error: file not found: " + req);
return new byte[0];
} else
return r;
}
/* run
* Handle a HTTP connection
* Read the HTTP request and handle accordingly
* GET requests all get the main html file
* AJAX requests are managed accordingly
*/
public void run() {
/*try {
Thread.currentThread().sleep(10000);
} catch (Exception e) {
res.alert("EXCEPTION : " + e.toString());
}
res.alert("Done waiting");*/
try {
// READ HTTP / AJAX call
BufferedReader sin = new BufferedReader(new InputStreamReader(sock.getInputStream()));
String header= "";
int i = 0;
int type = TYPE_POST;
String reqLine = "";
int contentLength = 0;
header = sin.readLine();
if (header == null) {
// no header, not a valid HTTP conn
res.log("Invalid connection");
return;
}
String userAgent = "agent";
while (header != null && header.length() >= 3) {
if ( header.substring(0, 3).equals("GET")) {
type = TYPE_GET;
reqLine = header;
} else if (header.length() > 4 && header.substring(0, 4).equals("POST")) {
reqLine = header;
reqLine = reqLine.substring(5);
int end = reqLine.indexOf(' ');
reqLine = reqLine.substring(0, end);
if (reqLine.charAt(0) == '/')
reqLine = reqLine.substring(1);
} else if (header.length() > 14 && header.substring(0, 14).toLowerCase().equals("content-length")) {
contentLength = Integer.parseInt(header.substring(16));
} else if (header.length() > 10 && header.substring(0, 10).equals("User-Agent")) {
//javax.swing.JOptionPane.showMessageDialog(null, header);
userAgent = header;
}
System.out.println(i + ": '" + header + "'");
i++;
header = sin.readLine();
}
//res.alert("Done reading header");
// Figure out response
String ajax_resp="";
byte[] get_resp= null;
String CODE = "200 OK";
int resp_length = 0;
if (type == TYPE_GET) {
reqLine = reqLine.substring(4);
res.log("GET " + reqLine);
get_resp = handleGet(reqLine);
if (get_resp.length == 0) {
CODE = "404 Not Found";
}
resp_length = get_resp.length;
} else {
// No forward
if (reqLine.equals("")) {
//res.alert("no forward, parse ajax");
HashMap<String, String> req = parseAjax(sin);
//res.alert("handleAjax");
ajax_resp = handleAjax(req);
//res.alert("ajax resp: " + ajax_resp);
} else { // Forward request to node
//res.log("AJAX forward to '" + reqLine + "'");
ajax_resp = reqLine;
ajax_resp = ajaxCall(reqLine, sin);
}
resp_length = ajax_resp.length();
}
// HTTP Response
PrintWriter sout = new PrintWriter(sock.getOutputStream(), true);
Date now = new java.util.Date();
SimpleDateFormat formater = new SimpleDateFormat("E, d M y H:m:s z");
sout.print("HTTP/1.1 " + CODE + "\r\n"+
"Date: " + formater.format(now) + "\r\n" +
"Content-Type: text/html; charset=UTF-8\r\n" +
"Server: Cortex @ " + Integer.toString(res.PORT) + "\r\n");
// Print response
sout.print("Content-Length: " + resp_length + "\r\n" +
"\r\n");
sout.flush();
if (type == TYPE_GET) {
//sout.write(get_resp);
sock.getOutputStream().write(get_resp);
} else {
sout.print(ajax_resp);
//res.alert("ajax returning: " + ajax_resp);
}
sout.flush();
sin.close();
sout.close();
sock.close();
} catch (IOException e) {
res.error( "IOException in ConnHandler.run(): " + e.toString());
System.out.println("IOException in ConnHandler.run()");
}
System.out.println("DONE run()");
}
}

88
Cortex.java

@ -0,0 +1,88 @@
import java.applet.*;
//import java.awt.*;
import java.awt.event.*;
import javax.swing.Timer;
import java.awt.image.*;
import java.lang.*;
import java.io.*;
import java.net.*;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import javax.swing.JOptionPane.*;
public class Cortex extends Applet {
//private final int PORT = 2600; // in ResManager now
private ServerSocket server;
private ResManager res = new ResManager();
/*URL getCodeBase() throws Exception {
return new URL("file:///home/dan/src/school/cpsc416/cortex/");
}*/
/* main
* Main HTTP server. Accepts connections on PORT and passes them to threads
* in the form of ConnHandlers to deal with
*/
public void init() {
//javax.swing.JOptionPane.showMessageDialog(null, "APPLET STARTING!!!!");
//res.alert("Starting...");
res.putNodeData("originURL", getCodeBase().toString());
res.reloadSite();
//res.alert("Loaded site");
boolean bound = false;
while(!bound)
{
try {
server = new ServerSocket(res.PORT);
bound = true;
} catch (IOException e) {
res.PORT++;
}
}
/*
try {
server = new ServerSocket(res.PORT);
} catch (IOException e) {
res.error( "It appears another Cortex Node is already running on this computer, making this one superfulous.\nShutting down...");
}*/
/*try {
JSObject win = JSObject.getWindow(this);
win.eval("load();");
} catch(Exception e) {
res.error(e.toString());
}*/
try {
//res.alert("running server");
while (!res.killSwitch) {
Socket sock = server.accept();
//res.alert("ACCEPTED!");
new Thread(new ConnHandler(sock, res)).start();
//handler.run();
//res.alert("RESTARTING LOOP");
}
server.close();
} catch (IOException e) {
System.out.println("IOException in init(): " + e.toString());
res.error( "IOException in init(): " + e.toString());
}
//res.error("QUITING!");
}
}

15
Makefile

@ -0,0 +1,15 @@
Cortex.jar: Cortex.class ConnHandler.class ResManager.class
jar cvf Cortex.jar Cortex.class ConnHandler.class ResManager.class
jarsigner Cortex.jar cortex_cert
ResManager.class: ResManager.java
javac ResManager.java
ConnHandler.class: ConnHandler.java
javac ConnHandler.java
Cortex.class: Cortex.java
javac Cortex.java
clean:
rm -f *.class *.jar

179
ResManager.java

@ -0,0 +1,179 @@
import java.util.HashMap;
import javax.swing.JOptionPane.*;
import java.util.ArrayList;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import javax.swing.JOptionPane.*;
import java.lang.*;
import java.io.*;
import java.net.*;
class ResManager {
public /*final*/ int PORT = 2600;
private HashMap<String, byte[]> site = new HashMap<String, byte[]>();
private HashMap<String, String> nodeData = new HashMap<String, String>();
private ArrayList<String> log = new ArrayList<String>();
private boolean logLock = false;
private DateFormat logDateFormat = new SimpleDateFormat("HH:mm:ss");
private boolean mqLock = false;
private ArrayList<String> msgQueue = new ArrayList<String>();
public boolean killSwitch = false;
public ResManager() {
}
public void putSite(String key, byte[] val) {
site.put(key, val);
}
public byte[] getSite(String key) {
return site.get(key);
}
public void putNodeData(String key, String val) {
nodeData.put(key, val);
}
public String getNodeData(String key) {
return nodeData.get(key);
}
private synchronized void logLock() {
while (logLock == true) {
try {
wait();
} catch (Exception e) {
error("logLock: " + e.toString());
}
}
logLock = true;
//javax.swing.JOptionPane.showMessageDialog(null, " Locked");
}
private synchronized void logUnlock() {
logLock = false;
//javax.swing.JOptionPane.showMessageDialog(null, " UnLocked");
}
public synchronized void log(String l) {
logLock();
Date d = new Date();
log.add(logDateFormat.format(d) + ": " + l);
logUnlock();
}
private synchronized void mqLock() {
while(mqLock == true) {
try {
wait();
} catch (Exception e) {
error("mqLock: " + e.toString());
}
}
mqLock = true;
}
private synchronized void mqUnlock() {
mqLock = false;
}
public synchronized void queueMsg(String m) {
mqLock();
msgQueue.add(m);
mqUnlock();
}
public synchronized ArrayList<String> getMsgs() {
mqLock();
ArrayList<String> mq = msgQueue;
msgQueue = new ArrayList<String>();
mqUnlock();
return mq;
}
public void alert(String a) {
javax.swing.JOptionPane.showMessageDialog(null, a);
log("ALERT> " + a);
}
public void error(String e) {
javax.swing.JOptionPane.showMessageDialog(null, e);
log("ERROR> " + e);
}
// returns the current log and RESETS it
public synchronized ArrayList<String> getLog()
{
logLock();
ArrayList<String> tmp = log;
log = new ArrayList<String>();
logUnlock();
return tmp;
}
public void reloadSite() {
String baseurl = getNodeData("originURL");
try {
putSite("Cortex.jar", readURL(new URL(baseurl + "Cortex.jar")));
putSite("Cortex.class", readURL(new URL(baseurl + "Cortex.jar")));
putSite("client.html", readURL(new URL(baseurl + "client.html")));
putSite("shell.html", readURL(new URL(baseurl + "shell.html")));
putSite("ajax.js", readURL(new URL(baseurl + "ajax.js")));
} catch (Exception e) {
error( "URL Exception in ResManager.reloadSite(): " + e.toString());
}
}
private byte[] readURL(URL url) {
byte[] buff=null;
try {
URLConnection urlConn = url.openConnection();
urlConn.setDoInput(true);
urlConn.setUseCaches(false);
DataInputStream dis = new DataInputStream(urlConn.getInputStream());
int length = urlConn.getContentLength();
buff = new byte[length];
int totalRead = 0;
while ( totalRead != length) {
totalRead += dis.read(buff, totalRead, length-totalRead); //, 0, length);
//alert(totalRead + "/" + length);
}
return buff;
} catch (Exception e) {
error( "Exception in ResManager.readURLIntoBuff(): " + e.toString());
return null;
}
}
/*
public synchronized void put(String key, String val) {
//javax.swing.JOptionPane.showMessageDialog(null, "putting: '" + key + "'");
//javax.swing.JOptionPane.showMessageDialog(null, val);
//data.put(key, val);
}
public synchronized String get(String key) {
//javax.swing.JOptionPane.showMessageDialog(null, "getting: '" + key + "'");
//javax.swing.JOptionPane.showMessageDialog(null, "from: " + data.keySet().toString());
//return data.get(key);
}*/
}

6
Runner.java

@ -0,0 +1,6 @@
class Runner {
public static void main(String[] args) {
Cortex c = new Cortex();
c.init();
}
}

94
TSP_map_test.js

@ -0,0 +1,94 @@
function map_test(value)
{
var TSPSatSolverHelper = function(graph, current, visited, distance, numberVisited, order, res)
{
visited[current] = numberVisited;
if (distance - graph[current][0] < 0)
{
visited[current] = 0;
return false;
}
if (numberVisited >= graph.length)
{
for (var index = 0; index < visited.length; index++)
order[visited[index] - 1] = index;
visited[current] = 0;
return true;
}
for (var next = 0; next < graph.length; next++)
if (graph[current][next] != 0 && visited[next] <= 0 && TSPSatSolverHelper(graph, next, visited, distance - graph[current][next], numberVisited + 1, order))
return true;
visited[current] = 0;
return false;
}
var TSPSatSolver = function(graph, distance, order)
{
var visited = new Array(graph.length);
for (var index = 0; index < graph.length; index++)
visited[index] = 0;
return TSPSatSolverHelper(graph, 0, visited, distance, 1, order, false);
}
var cities = 8;
var graph = [ [0,8,2,4,5,7,0,0],
[8,0,0,5,0,2,3,4],
[2,0,0,1,7,0,8,3],
[4,5,1,0,0,0,3,2],
[5,0,7,0,0,1,5,6],
[7,2,0,0,1,0,1,4],
[0,3,8,3,5,1,0,0],
[0,4,3,2,6,4,0,0]];
//new Array(cities);
var order = new Array(cities);
for (var index = 0; index < cities; index++)
order[index] = 0;
/*for (var row = 0; row < graph.length; row++)
graph[row] = new Array(cities);
for(var ii = 0; ii < cities; ii++)
for(var jj = 0; jj < cities; jj++)
graph[ii][jj] = (ii == jj ? 0 : 2);
graph[1][2] = 1;
graph[2][1] = 1;
graph[1][3] = 1;
graph[3][1] = 1;
*/
var result = TSPSatSolver(graph, value, order);
//return result;
if (result == true)
return order;
else
return false;
}
function reduce(list)
{
var r = new Array();
for (var i = 0; i < list.length; i++)
{
if (list[i].value != false)
{
r.push(list[i]);
break;
}
}
return r;
}

47
ajax.js

@ -0,0 +1,47 @@
var port = location.href.substring( location.href.substring(7).indexOf(':')+8,
location.href.substring(7).indexOf('/')+7);
// Returns an ajax object
function ajaxConnect() {
var http = null;
if(window.XMLHttpRequest)
http = new XMLHttpRequest();
else if (window.ActiveXObject)
http = new ActiveXObject("Microsoft.XMLHTTP");
return http;
}
/* returns a function that can be passed to http.send
* that runs code fn on successful response
* http: ajac object
* fn: function taking one argument, the response string
* run if successful connection
* err: OPTIONAL argument that contains a funtion
* to be run if the connection failed
*/
function returnfn(http, fn, err) {
if (!fn)
fn = function(resp) {};
if (!err)
err = function() {};
return function() {
if (http.readyState == 4) {
if (http.responseText == '')
err();
else
fn(http.responseText);
}
};
}
// Does ajax magic. Makes ajax call with data and sets up
// retfn to be called on response
function ajaxSend(http, data, retfn, forward) {
if (!forward)
forward = '';
http.onreadystatechange = retfn;
http.open('POST', "http://localhost:"+port+"/"+ forward, true);
http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
http.send(data);
}

1973
client.html
File diff suppressed because it is too large
View File

8
gen-cert.sh

@ -0,0 +1,8 @@
#!/bin/sh
# 5 years should be good
VALIDITY=1825
echo "Deleting old cortex_cert..."
keytool -delete -alias cortex_cert
echo "Generating new cortex_cert"
keytool -genkey -alias cortex_cert -validity $VALIDITY

43
shell.html

@ -0,0 +1,43 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Client</title>
<script src="ajax.js" ></script>
<script>
function load() {
port = document.getElementById('port').value;
document.getElementById('client').src = "http://localhost:" + port + "/client.html";
}
function isLoaded() {
if(document.getElementById('cortex').isActive())
{
load();
clearInterval();
}
}
</script>
</head>
<body>
<input type="button" value="Load" onClick="load()" />
<input id="port" size="4" value="2600" />
<applet code="Cortex.class" archive="Cortex.jar" width="50" height="50" id="cortex"></applet>
<b>Coretex Client</b><br/>
<iframe height="400" width="600" id="client" name="client">
</iframe>
</body>
</html>
Loading…
Cancel
Save