// Runs a story of FILIUS' web server (WebServer) and web browser // (WebBrowser) on a core scenario's network in Java FILIUS (ScenarioNetwork) // and records what really happens: every frame each card saw, every line the // server wrote into its window, and everything the browser told its window // (a page: its status, content type and text; or "update", when an image // came or failed). // // WebRun // // The stories use the network of web-lan (browser on 192.168.0.20, DNS // server .10, web server .30, a host without one .31). The web server runs // switched on, on port 80, with the files FILIUS gives it (index.html and // its image) and those below (files), its virtual hosts in /www.conf/vhosts. // An address is typed as into the browser's window and made into a URL as // the window does (GUIApplicationWebBrowserWindow.erzeugeURL). // page 192.168.0.30 // byName www.filius.de/seite.html (images found, missing, in a // folder, absolute), then a link without host: /text.txt // notFound http://www.filius.de/nichts.html // vhost seite.filius.de, andere.filius.de, www.filius.de/vhost1/ // noServer leer.filius.de (no web server there) // unresolved unbekannt.filius.de (no address) // post a form's POST to www.filius.de/seite.html // encoded www.filius.de/mein bild.html, www.filius.de/grüße.html // traversal www.filius.de/../geheim.txt // caseInsensitive WWW.Filius.de/SEITE.HTML // raw FILIUS' generic client on .20 talks to the server: a // request, then "HALLO"; connected anew, "GET /" without // a version // // files: every file of the server's file system at the end, path, type and // content, for the core to give its server the same. import filius.rahmenprogramm.EingabenUeberpruefung; import filius.software.clientserver.ClientBaustein; import filius.software.system.Datei; import filius.software.system.Dateisystem; import filius.software.www.HTTPNachricht; import filius.software.www.WebBrowser; import filius.software.www.WebServer; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeNode; public class WebRun { static final String BROWSER = "00000000-0000-0000-0000-000000000201"; static final String SERVER = "00000000-0000-0000-0000-000000000203"; static ScenarioNetwork network; static WebBrowser browser; static final List events = new ArrayList<>(); static synchronized void event(String who, String what) { events.add(new Object[] { System.currentTimeMillis() - network.start, who, what }); } static void sleepUntil(long milliseconds) throws InterruptedException { long rest = network.start + milliseconds - System.currentTimeMillis(); if (rest > 0) Thread.sleep(rest); } /** GUIApplicationWebBrowserWindow.erzeugeURL. */ static URL url(String ressource) throws Exception { String[] parts = ressource.split("/"); String host = null, path = ""; if (parts.length > 0 && !parts[0].equalsIgnoreCase("http:")) { if (EingabenUeberpruefung.isGueltig(parts[0], EingabenUeberpruefung.musterDomain) || EingabenUeberpruefung.isGueltig(parts[0], EingabenUeberpruefung.musterIpAdresse)) { host = parts[0]; for (int i = 1; i < parts.length; i++) path = path + "/" + parts[i]; } } if (parts.length > 2 && parts[0].equalsIgnoreCase("http:")) { if (EingabenUeberpruefung.isGueltig(parts[2], EingabenUeberpruefung.musterDomain) || EingabenUeberpruefung.isGueltig(parts[2], EingabenUeberpruefung.musterIpAdresse)) { host = parts[2]; } for (int i = 3; i < parts.length; i++) path = path + "/" + parts[i]; } if (host == null) return null; if (path.equals("")) path = "/"; return new URL("http", host, path); } static void open(String typed, String post) throws Exception { event("browser", "call holeWebseite " + typed + (post == null ? "" : " POST " + post)); URL url = url(typed); if (url == null) { event("browser", "no url"); } else if (post == null) { browser.holeWebseite(url); } else { browser.holeWebseite(url, post); } } static void file(Dateisystem files, String directory, String name, String type, String content) { files.speicherDatei(directory, new Datei(name, type, content)); } public static void main(String[] args) throws Exception { network = ScenarioNetwork.read(args[0]); String story = args[1]; long end = Long.parseLong(args[2]); network.system(SERVER).installApp("filius.software.www.WebServer", false); network.system(BROWSER).installApp("filius.software.www.WebBrowser", false); WebServer server = (WebServer) network.system(SERVER).holeSoftware("filius.software.www.WebServer"); browser = (WebBrowser) network.system(BROWSER).holeSoftware("filius.software.www.WebBrowser"); if (story.equals("raw")) { network.system(BROWSER).installApp("filius.software.clientserver.ClientBaustein", false); network.system(BROWSER).holeSoftware("filius.software.clientserver.ClientBaustein") .hinzuBeobachter((observable, data) -> event("client", String.valueOf(data))); } Dateisystem files = network.system(SERVER).getDateisystem(); String image = files.holeDatei("/webserver/splashscreen-mini.png").getDateiInhalt(); file(files, "/webserver", "seite.html", "html", "Seite

Seite

\n\n" + "\"x\""); file(files, "/webserver", "bild.png", "png", image); files.erstelleVerzeichnis("/webserver", "unter"); file(files, "/webserver/unter", "bild.png", "png", image); file(files, "/webserver", "text.txt", "txt", "Nur Text\nzwei Zeilen"); file(files, "/webserver", "mein bild.html", "html", "Leerzeichen"); file(files, "/webserver", "grüße.html", "html", "Umlaute"); file(files, "/", "geheim.txt", "txt", "geheim"); files.erstelleVerzeichnis("/", "www.conf"); file(files, "/www.conf", "vhosts", "", "seite.filius.de\nvhost1\nandere.filius.de\nvhost2\n"); files.erstelleVerzeichnis("/webserver", "vhost1"); file(files, "/webserver/vhost1", "index.html", "html", "Eins"); files.erstelleVerzeichnis("/webserver", "vhost2"); file(files, "/webserver/vhost2", "index.html", "html", "Zwei"); server.setAktiv(true); server.hinzuBeobachter((observable, data) -> event("server", String.valueOf(data))); browser.hinzuBeobachter((observable, data) -> { if (data instanceof HTTPNachricht) { HTTPNachricht page = (HTTPNachricht) data; event("browser", "page " + page.getStatusCode() + " " + page.getContentType() + "\n" + page.getDaten()); } else { event("browser", data == null ? "update" : String.valueOf(data)); } }); network.start(); sleepUntil(500); switch (story) { case "page": open("192.168.0.30", null); break; case "byName": open("www.filius.de/seite.html", null); sleepUntil(6000); open("http:///text.txt", null); break; case "notFound": open("http://www.filius.de/nichts.html", null); break; case "vhost": open("seite.filius.de", null); sleepUntil(5000); open("andere.filius.de", null); sleepUntil(9500); open("www.filius.de/vhost1/", null); break; case "noServer": open("leer.filius.de", null); break; case "unresolved": open("unbekannt.filius.de", null); break; case "post": open("www.filius.de/seite.html", "name=Filius&x=1"); break; case "encoded": open("www.filius.de/mein bild.html", null); sleepUntil(5000); open("www.filius.de/grüße.html", null); break; case "traversal": open("www.filius.de/../geheim.txt", null); break; case "caseInsensitive": open("WWW.Filius.de/SEITE.HTML", null); break; case "raw": { ClientBaustein client = (ClientBaustein) network.system(BROWSER).holeSoftware("filius.software.clientserver.ClientBaustein"); client.setZielIPAdresse("192.168.0.30"); client.setZielPort(80); event("client", "call verbinden"); client.verbinden(); sleepUntil(2500); event("client", "call senden GET /text.txt"); client.senden("GET /text.txt HTTP/1.1\nHost: 192.168.0.30\n"); sleepUntil(4500); event("client", "call senden HALLO"); client.senden("HALLO"); sleepUntil(7000); event("client", "call verbinden"); client.verbinden(); sleepUntil(9000); event("client", "call senden GET /"); client.senden("GET /"); break; } default: throw new IllegalArgumentException("unknown story " + story); } sleepUntil(end); ScenarioNetwork.Json out = new ScenarioNetwork.Json(); out.open('{'); network.writeFrames(out); synchronized (WebRun.class) { out.key("events").open('['); for (Object[] each : events) out.open('[').number((Long) each[0]).string((String) each[1]).string((String) each[2]).close(']'); out.close(']'); } out.key("files").open('['); Enumeration nodes = files.getRoot().preorderEnumeration(); while (nodes.hasMoreElements()) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) nodes.nextElement(); if (!(node.getUserObject() instanceof Datei)) continue; Datei datei = (Datei) node.getUserObject(); out.open('[').string(Dateisystem.absoluterPfad(node)).string(datei.getDateiTyp()).string(datei.getDateiInhalt()).close(']'); } out.close(']'); out.close('}'); network.stop(); ScenarioNetwork.write(args[3], out); System.exit(0); } }