Compare commits

...

10 commits

5 changed files with 77 additions and 36 deletions

View file

@ -1,14 +1,10 @@
package de.tudbut.tryumph;
import java.util.Arrays;
import de.tudbut.async.Task;
import de.tudbut.tryumph.config.IRequestCatcher;
import de.tudbut.tryumph.config.RequestCatcherConfig;
import de.tudbut.tryumph.config.TryConfig;
import de.tudbut.tryumph.err.ProjectException;
import de.tudbut.tryumph.server.http.Server;
import de.tudbut.tryumph.util.Bug;
import tudbut.global.DebugStateManager;
public class Launch {
@ -32,7 +28,7 @@ public class Launch {
IRequestCatcher requestCatcher = catcher.load().ok().await();
server.listen(requestCatcher);
} catch(Throwable e) {
throw new Bug("HTTP server died, but all errors from HTTP should usually be catched", e);
throw new Error("HTTP Server died.", e);
}
}

View file

@ -1,5 +1,6 @@
package de.tudbut.tryumph.example;
import java.io.File;
import java.net.Socket;
import org.w3c.dom.Document;
@ -7,12 +8,14 @@ import org.w3c.dom.Element;
import de.tudbut.async.Callback;
import de.tudbut.async.ComposeCallback;
import de.tudbut.async.Task;
import de.tudbut.async.TaskCallable;
import de.tudbut.tryumph.config.IRequestCatcher;
import de.tudbut.tryumph.config.TryConfig;
import de.tudbut.tryumph.events.GET;
import de.tudbut.tryumph.events.Path;
import de.tudbut.tryumph.events.RequestHandler;
import de.tudbut.tryumph.server.BrowserContext;
import de.tudbut.tryumph.server.Request;
import de.tudbut.tryumph.server.Response;
import tudbut.parsing.TCN;
@ -58,28 +61,28 @@ public class FileServer implements IRequestCatcher, RequestHandler.Listener {
private String fileContent(Request request, String s) {
String r;
if(!s.endsWith(".html") && !s.endsWith(".htm")) {
r = request.context.file(s);
if(new File(s + "/index.html").exists())
s += "/index.html";
if(!s.endsWith(".html") && !s.endsWith(".htm") && !(new File(s).isDirectory())) {
r = request.context.fileUTF(s, data.getBoolean("autoindex") ? request.realPath : null);
r = "<pre>" + r.replace("<", "&lt;").replace(">", "&gt;") + "</pre>";
}
else
r = request.context.fileUTF(s);
r = request.context.fileUTF(s, data.getBoolean("autoindex") ? request.realPath : null);
return r;
}
@GET
@Path(".*/")
public void onIndex(Request request, Callback<Response> res, Callback<Throwable> rej) {
res.call(new Response(request, fileContent(request, data.getString("dir") + request.realPath.replace("..", "") + "/index.html"), 200, "OK"));
}
@GET
@Path("/.+")
@Path("/.*")
public void onFile(Request request, Callback<Response> res, Callback<Throwable> rej) {
if(request.realPath.equals("/style.css")) {
res.call(new Response(request, request.context.file("style.css"), 200, "OK", "text/css"));
return;
}
if(request.realPath.matches("/.$|/./|/..$|/../")) {
res.call(new Response(request, "<h1>" + request.realPath + " is an illegal path</h1>", 400, "Bad request"));
return;
}
res.call(new Response(request, fileContent(request, data.getString("dir") + request.realPath.replace("..", "")), 200, "OK"));
}
@ -88,4 +91,13 @@ public class FileServer implements IRequestCatcher, RequestHandler.Listener {
rej.call(error);
}
@Override
public Task<BrowserContext> processBrowserContext(BrowserContext context) {
if(data.getBoolean("noscript") != null)
context.addJavaScript = !data.getBoolean("noscript");
if(data.getBoolean("cookies") != null)
context.addState = data.getBoolean("cookies");
return IRequestCatcher.super.processBrowserContext(context);
}
}

View file

@ -3,6 +3,7 @@ package de.tudbut.tryumph.server;
import static de.tudbut.async.Async.*;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
@ -26,8 +27,9 @@ public class BrowserContext {
public final UUID uuid = UUID.randomUUID();
public TCN data;
private final IRequestCatcher requestCatcher;
public boolean useJavaScript = false;
private boolean needsChange = false;
public boolean addState = true;
public boolean addJavaScript = true;
private BrowserContext(IRequestCatcher requestCatcher) {
this.requestCatcher = requestCatcher;
@ -64,7 +66,8 @@ public class BrowserContext {
private Task<BrowserContext> init() {
return t((res, rej) -> {
requestCatcher.processBrowserContext(this).err(rej).then(res).ok();
needsChange = true;
if(addState)
needsChange = true;
});
}
@ -77,7 +80,7 @@ public class BrowserContext {
public Task<Response> onSend(Response response) {
return AsyncJSON.write(data)
.compose((resp, res, rej) -> {
if(response.isHTML) {
if(addJavaScript && response.isHTML) {
Document document = response.getHTML();
Element element = document.createElement("script");
Node text = document.createTextNode(
@ -109,11 +112,13 @@ public class BrowserContext {
head.appendChild(element);
response.updateHTMLData();
}
if(needsChange) {
response.cookiesToSet.put("tryumph.data", resp);
needsChange = false;
if(addState) {
if(needsChange) {
response.cookiesToSet.put("tryumph.data", resp);
needsChange = false;
}
response.cookiesToSet.put("tryumph.uuid", uuid.toString());
}
response.cookiesToSet.put("tryumph.uuid", uuid.toString());
res.call(response);
});
}
@ -124,20 +129,37 @@ public class BrowserContext {
private static final HashMap<String, String> cache = new HashMap<>();
public String file(String file) {
return file(file, null);
}
public String fileUTF(String file) {
return fileUTF(file, null);
}
public String file(String file, String path) {
if(cache.containsKey(file))
return cache.get(file);
StringBuilder builder = new StringBuilder();
try {
InputStream stream = requestCatcher.getClass().getClassLoader().getResourceAsStream(file);
if(stream == null)
if(stream == null) {
if(new File(file).isDirectory() && path != null) {
while(path.endsWith("/")) path = path.substring(0, path.length() - 1);
File[] files = new File(file).listFiles();
builder.append("<ul>");
for(int i = 0; i < files.length; i++) {
builder.append("<li><a href=\"" + path + "/" + files[i].getName() + "\">" + files[i].getName() + "</a></li>");
}
builder.append("</ul>");
return builder.toString();
}
stream = new FileInputStream(file);
}
int i = 0;
while((i = stream.read()) != -1) {
builder.append((char) i);
}
stream.close();
if(!TryConfig.nocache)
cache.put(file, builder.toString());
} catch (IOException e) {
@ -146,14 +168,26 @@ public class BrowserContext {
}
return builder.toString();
}
public String fileUTF(String file) {
public String fileUTF(String file, String path) {
if(cache.containsKey(file))
return cache.get(file);
String st = null;
try {
InputStream stream = requestCatcher.getClass().getClassLoader().getResourceAsStream(file);
if(stream == null)
if(stream == null) {
if(new File(file).isDirectory() && path != null) {
while(path.endsWith("/")) path = path.substring(0, path.length() - 1);
File[] files = new File(file).listFiles();
StringBuilder builder = new StringBuilder();
builder.append("<ul>");
for(int i = 0; i < files.length; i++) {
builder.append("<li><a href=\"" + path + "/" + files[i].getName() + "\">" + files[i].getName() + "</a></li>");
}
builder.append("</ul>");
return builder.toString();
}
stream = new FileInputStream(file);
}
ByteArrayOutputStream s = new ByteArrayOutputStream();
int i = 0;
@ -164,6 +198,7 @@ public class BrowserContext {
stream.close();
s.close();
st = new String(s.toByteArray());
if(!TryConfig.nocache)
cache.put(file, st);
} catch (IOException e) {

View file

@ -93,18 +93,11 @@ public class Server {
break;
}
} catch (Stop stop) {
if(stop.getMessage() != null) {
System.out.println("Connection stopped: " + stop.getMessage());
}
else {
System.out.println("Connection stopped");
}
}
try {
socket.close();
} catch (IOException e) {
}
System.out.println("Connection with " + socket + " ended");
socket.close();
} catch (IOException e) {
}
}).start();
}
serverSocket.close();

View file

@ -39,3 +39,8 @@ input,button,select {
input.button,button,select {
border: 1px solid #cdd;
}
a {
color: #fff;
text-decoration: underline dashed #888 1px;
}