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>
This commit is contained in:
@@ -0,0 +1,237 @@
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user