Files
mdg-filius/tools/java-oracle/src/WebRun.java
T
julian.kiedaischandClaude Opus 5.5 4cd5749350 feat(core): FILIUS' web server and web browser after Java, measured against Java
The servers share ServerAnwendung's frame (server.ts); the web server serves
/webserver with virtual hosts, the browser loads a page and its images over
one connection to port 80 (web.ts); HTTP in Java's text form (http.ts).
WebRun records eleven stories on the new web-lan network, with the server's
files; webJava.test.ts plays them card by card. A program's close is a
request, as Java's schliessen. Not taken from Java: /../ serving any file of
the host; an unreadable request closing the connection without a word.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 16:53:00 +00:00

238 lines
11 KiB
Java

// 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 <scenario.json> <story> <milliseconds> <out.json>
//
// 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<Object[]> 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",
"<html><head><title>Seite</title></head><body><h1>Seite</h1>\n<img src=\"bild.png\"><IMG SRC='fehlt.png'>\n"
+ "<img alt=\"x\" src=unter/bild.png><img src=\"/bild.png\"></body></html>");
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", "<html><body>Leerzeichen</body></html>");
file(files, "/webserver", "grüße.html", "html", "<html><body>Umlaute</body></html>");
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", "<html><body>Eins</body></html>");
files.erstelleVerzeichnis("/webserver", "vhost2");
file(files, "/webserver/vhost2", "index.html", "html", "<html><body>Zwei</body></html>");
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<TreeNode> 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);
}
}