From 0e14ae6d273d478fb17b2d1d5f0ef2baea387948 Mon Sep 17 00:00:00 2001 From: stilscher <66023521+stilscher@users.noreply.github.com> Date: Thu, 2 Nov 2023 16:43:43 +0100 Subject: [PATCH 1/4] serve dist directory if possible and docs directory otherwise --- goblint-http-server/goblint_http.ml | 80 +++++++++++++---------------- 1 file changed, 37 insertions(+), 43 deletions(-) diff --git a/goblint-http-server/goblint_http.ml b/goblint-http-server/goblint_http.ml index 26c22c4..8581c77 100644 --- a/goblint-http-server/goblint_http.ml +++ b/goblint-http-server/goblint_http.ml @@ -6,6 +6,7 @@ open Lwt.Infix module Yojson_conv = Ppx_yojson_conv_lib.Yojson_conv let docroot = ref "run" +let distroot = ref "gobview_dist" let index = ref "index.html" let addr = ref "127.0.0.1" let port = ref 8080 @@ -15,7 +16,8 @@ let rest = ref [] let specs = [ - ("-docroot", Arg.Set_string docroot, "Serving directory"); + ("-docroot", Arg.Set_string docroot, "Serving directory for marshalled data"); + ("-distroot", Arg.Set_string distroot, "Serving directory for distribution files"); ("-index", Arg.Set_string index, "Name of index file in directory"); ("-addr", Arg.Set_string addr, "Listen address"); ("-port", Arg.Set_int port, "Listen port"); @@ -45,8 +47,8 @@ let process state name body = (fun exn -> Server.respond_error ~status:`Bad_request ~body:(Printexc.to_string exn) ()) (* The serving of files is implemented similar as in the binary https://github.com/mirage/ocaml-cohttp/blob/master/cohttp-lwt-unix/bin/cohttp_server_lwt.ml *) -let serve_file ~docroot ~uri = - let fname = Cohttp.Path.resolve_local_file ~docroot ~uri in +let serve_file ~root ~uri = + let fname = Cohttp.Path.resolve_local_file ~docroot:root ~uri in Server.respond_file ~fname () let sort lst = @@ -91,48 +93,40 @@ let html_of_listing uri path listing = (Uri.pct_decode path) contents let serve uri path = - let file_name = Cohttp.Path.resolve_local_file ~docroot:!docroot ~uri in + let file_name_dist = Cohttp.Path.resolve_local_file ~docroot:!distroot ~uri in + let file_name_docs = Cohttp.Path.resolve_local_file ~docroot:!docroot ~uri in + + let lookup file_name root () = + (Lwt_unix.lstat file_name) >>= (fun (stat_dist) -> + (* for symbolic links lstat returns S_LNK, which will result in a forbidden error in this + implementation. Use stat instead if symbolic links to folders or files should be handled + just like folders or files respectively *) + match stat_dist.Unix.st_kind with + | Unix.S_DIR -> ( + let path_len = String.length path in + if path_len <> 0 && path.[path_len - 1] <> '/' then ( + Server.respond_redirect ~uri:(Uri.with_path uri (path ^ "/")) ()) + else ( + match Sys.file_exists (Filename.concat file_name !index) with + | true -> ( + let uri = Uri.with_path uri (Filename.concat path !index) in + serve_file ~root ~uri) + | false -> + Lwt.fail Not_found)) + | Unix.S_REG -> serve_file ~root ~uri + | _ -> Lwt.fail Not_found) in + Lwt.catch - (fun () -> - Lwt_unix.lstat file_name >>= fun stat -> (* for symbolic links lstat returns S_LNK, which will result in a - forbidden error in this implementation. Use stat instead if symbolic links to folders or files should be handled - just like folders or files respectively *) - match stat.Unix.st_kind with - | Unix.S_DIR -> ( - let path_len = String.length path in - if path_len <> 0 && path.[path_len - 1] <> '/' then ( - Server.respond_redirect ~uri:(Uri.with_path uri (path ^ "/")) ()) - else ( - match Sys.file_exists (Filename.concat file_name !index) with - | true -> ( - let uri = Uri.with_path uri (Filename.concat path !index) in - serve_file ~docroot:!docroot ~uri) - | false -> - let%lwt files = Lwt_stream.to_list - (Lwt_stream.filter (fun s -> s <> "." && s <> "..") (Lwt_unix.files_of_directory file_name)) in - let%lwt listing = Lwt_list.map_s (fun f -> - let file_name = Filename.concat file_name f in - Lwt.try_bind - (fun () -> Lwt_unix.LargeFile.stat file_name) - (fun stat -> - Lwt.return - ( Some - stat.Unix.LargeFile.st_kind, - f )) - (fun _exn -> Lwt.return (None, f))) files in - let body = html_of_listing uri path (sort listing) in - Server.respond_string ~status:`OK ~body ())) - | Unix.S_REG -> serve_file ~docroot:!docroot ~uri - | _ -> ( - let body = Printf.sprintf "

Forbidden

%s is not a normal file or \ - directory


" path in - Server.respond_string ~status:`OK ~body ())) + (lookup file_name_dist !distroot) (function - | Unix.Unix_error (Unix.ENOENT, "stat", p) as e -> - if p = file_name then ( - Server.respond_not_found ()) - else Lwt.fail e - | e -> Lwt.fail e) + | _ -> + Lwt.catch (lookup file_name_docs !docroot) + (function + | Unix.Unix_error (Unix.ENOENT, "stat", p) as e -> + if p = file_name_docs then ( + Server.respond_not_found ()) + else Lwt.fail e + | e -> Lwt.fail e)) let callback state _ req body = let uri = Request.uri req in From 2b1b722176992de7b964fda132e68f49c93c1f80 Mon Sep 17 00:00:00 2001 From: stilscher <66023521+stilscher@users.noreply.github.com> Date: Fri, 8 Dec 2023 15:31:52 +0100 Subject: [PATCH 2/4] use dune promote to copy distribution files to gobview top-level --- dune | 2 +- goblint-http-server/goblint_http.ml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dune b/dune index 3cf0148..1f81c17 100644 --- a/dune +++ b/dune @@ -1,6 +1,6 @@ (rule (alias gobview) - (targets dist) + (mode promote) (deps src/App.bc.js goblint-http-server/goblint_http.exe node_modules webpack.config.js) (action (run npx webpack build))) diff --git a/goblint-http-server/goblint_http.ml b/goblint-http-server/goblint_http.ml index 8581c77..238f8d0 100644 --- a/goblint-http-server/goblint_http.ml +++ b/goblint-http-server/goblint_http.ml @@ -6,7 +6,7 @@ open Lwt.Infix module Yojson_conv = Ppx_yojson_conv_lib.Yojson_conv let docroot = ref "run" -let distroot = ref "gobview_dist" +let distroot = ref "gobview/dist" let index = ref "index.html" let addr = ref "127.0.0.1" let port = ref 8080 From 69a962db09cf39ec658a754abc1c65d03e2d9d13 Mon Sep 17 00:00:00 2001 From: stilscher <66023521+stilscher@users.noreply.github.com> Date: Fri, 8 Dec 2023 18:27:21 +0100 Subject: [PATCH 3/4] let dist files be copied in make.sh --- .gitignore | 6 +++++- dune | 2 +- goblint-http-server/goblint_http.ml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 8555270..631d11a 100755 --- a/.gitignore +++ b/.gitignore @@ -24,7 +24,8 @@ .LSOverride # Icon must end with two \r -Icon +Icon + # Thumbnails ._* @@ -170,6 +171,9 @@ dist # ocamlbuild working directory _build/ +# distribution files +_dist/ + # ocamlbuild targets *.byte *.native diff --git a/dune b/dune index 1f81c17..d509b3c 100644 --- a/dune +++ b/dune @@ -1,6 +1,6 @@ (rule (alias gobview) - (mode promote) + (target dist) (deps src/App.bc.js goblint-http-server/goblint_http.exe node_modules webpack.config.js) (action (run npx webpack build))) diff --git a/goblint-http-server/goblint_http.ml b/goblint-http-server/goblint_http.ml index 238f8d0..f053274 100644 --- a/goblint-http-server/goblint_http.ml +++ b/goblint-http-server/goblint_http.ml @@ -6,7 +6,7 @@ open Lwt.Infix module Yojson_conv = Ppx_yojson_conv_lib.Yojson_conv let docroot = ref "run" -let distroot = ref "gobview/dist" +let distroot = ref "gobview/_dist" let index = ref "index.html" let addr = ref "127.0.0.1" let port = ref 8080 From 43d5ad357370a637e6654a958e19c2c42526d765 Mon Sep 17 00:00:00 2001 From: stilscher <66023521+stilscher@users.noreply.github.com> Date: Tue, 30 Jan 2024 18:41:08 +0100 Subject: [PATCH 4/4] promote executable and copy dist folder with dune --- dune | 4 +++- goblint-http-server/dune | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/dune b/dune index d509b3c..4c4582d 100644 --- a/dune +++ b/dune @@ -3,7 +3,9 @@ (target dist) (deps src/App.bc.js goblint-http-server/goblint_http.exe node_modules webpack.config.js) (action - (run npx webpack build))) + (progn + (run npx webpack build) + (system "mkdir -p ../../../gobview/_dist && cp -f ./dist/* ../../../gobview/_dist/")))) (rule (targets node_modules) diff --git a/goblint-http-server/dune b/goblint-http-server/dune index 6b78d44..55f78c1 100644 --- a/goblint-http-server/dune +++ b/goblint-http-server/dune @@ -1,6 +1,7 @@ (executable (name goblint_http) (public_name goblint-http) + (promote (until-clean) (into ../..)) (libraries batteries.unthreaded cohttp