|
@@ -4,16 +4,12 @@ namespace Astralis {
|
|
|
|
|
|
|
|
public class Server : Object {
|
|
public class Server : Object {
|
|
|
private Daemon daemon;
|
|
private Daemon daemon;
|
|
|
- private Router router;
|
|
|
|
|
|
|
+ private HttpHandler handler;
|
|
|
private int port;
|
|
private int port;
|
|
|
|
|
|
|
|
- public Server(int port) {
|
|
|
|
|
|
|
+ public Server(int port, HttpHandler handler) {
|
|
|
this.port = port;
|
|
this.port = port;
|
|
|
- this.router = new Router();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public void map_get(string path, owned RouteHandler handler) {
|
|
|
|
|
- router.map_get(path, (owned) handler);
|
|
|
|
|
|
|
+ this.handler = handler;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private int access_handler (Connection connection, string? url, string? method, string? version, string? upload_data, size_t* upload_data_size, void** con_cls) {
|
|
private int access_handler (Connection connection, string? url, string? method, string? version, string? upload_data, size_t* upload_data_size, void** con_cls) {
|
|
@@ -32,42 +28,25 @@ namespace Astralis {
|
|
|
return Result.YES;
|
|
return Result.YES;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- var request = new HttpRequest(connection, url ?? "", method ?? "", version ?? "");
|
|
|
|
|
- var response = new HttpResponse();
|
|
|
|
|
- var context = new HttpContext(request, response);
|
|
|
|
|
|
|
+ var request = new Request(url ?? "", method ?? "", version ?? "");
|
|
|
|
|
+ var context = new HttpContext(connection, request);
|
|
|
|
|
+ MHD.suspend_connection(connection);
|
|
|
|
|
|
|
|
- bool handled = router.handle(context);
|
|
|
|
|
-
|
|
|
|
|
- if (!handled) {
|
|
|
|
|
- response.status_code = 404;
|
|
|
|
|
- response.body = "Not Found";
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ handler.handle.begin(context, (obj, res) => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ handler.handle.end(res);
|
|
|
|
|
+ }
|
|
|
|
|
+ catch(Error e) {
|
|
|
|
|
+ handle_error(e, context);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
- // Create MHD response
|
|
|
|
|
- var mhd_response = new Response.from_buffer(
|
|
|
|
|
- response.body.length,
|
|
|
|
|
- response.body.data,
|
|
|
|
|
- ResponseMemoryMode.RESPMEM_MUST_COPY
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- mhd_response.add_header("Content-Type", response.content_type);
|
|
|
|
|
-
|
|
|
|
|
- int ret = MHD.queue_response(connection, response.status_code, mhd_response);
|
|
|
|
|
-
|
|
|
|
|
- // In C we'd destroy response here, but Vala handles memory management via the binding's free_function hopefully,
|
|
|
|
|
- // OR we'd need to be careful. The VAPI says free_function = MHD_destroy_response, so Vala will call it when the object goes out of scope.
|
|
|
|
|
- // However, MHD_queue_response usually increments refcount or copies?
|
|
|
|
|
- // Actually MHD_create_response.. returns a response with refcount 1.
|
|
|
|
|
- // MHD_queue_response increments it.
|
|
|
|
|
- // So if our wrapper object dies, it calls destroy, which decrements.
|
|
|
|
|
- // That should be correct.
|
|
|
|
|
-
|
|
|
|
|
- return ret;
|
|
|
|
|
|
|
+ return Result.YES;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public void run() {
|
|
public void run() {
|
|
|
daemon = Daemon.start(
|
|
daemon = Daemon.start(
|
|
|
- MHD.USE_SELECT_INTERNALLY | MHD.USE_DEBUG,
|
|
|
|
|
|
|
+ MHD.USE_SELECT_INTERNALLY | MHD.ALLOW_SUSPEND_RESUME | MHD.USE_DEBUG,
|
|
|
(uint16) this.port,
|
|
(uint16) this.port,
|
|
|
null,
|
|
null,
|
|
|
(connection, url, method, version, upload_data, upload_data_size, con_cls) => {
|
|
(connection, url, method, version, upload_data, upload_data_size, con_cls) => {
|
|
@@ -84,5 +63,10 @@ namespace Astralis {
|
|
|
print(@"Server running on port $port\nPress Ctrl+C to stop...\n");
|
|
print(@"Server running on port $port\nPress Ctrl+C to stop...\n");
|
|
|
new MainLoop().run();
|
|
new MainLoop().run();
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ private void handle_error(Error error, HttpContext context) {
|
|
|
|
|
+ printerr(@"Astralis Internal Server Error: Unhandled Error: $(error.message)\n");
|
|
|
|
|
+ context.respond_string(StatusCode.INTERNAL_SERVER_ERROR, "Internal Server Error");
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|