simple-learning

Simple learning web program
git clone git://git.laack.co/simple-learning.git
Log | Files | Refs | README | LICENSE

commit daea940887b250dd1758de279fdb0abb74477b41
parent 4ad8279a13e5ef52372a9449c2b7a3eaa542cd48
Author: Andrew Laack <andrew@laack.co>
Date:   Wed,  2 Sep 2026 11:49:14 -0500

Refactored page param handling, added more server tests.

Diffstat:
Mlearning/lib/server.ml | 21+++++++++++++++------
Mlearning/test/test_server.ml | 9++++++---
2 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/learning/lib/server.ml b/learning/lib/server.ml @@ -42,7 +42,9 @@ let my_error_template _error debug_info suggested_response = let get_course_name request = Dream.param request "course_name" - + +let get_page_name request = + Dream.param request "page_name" (* TODO: When should trailing slash be in a url? *) (* TODO: If sticking with course_name/ then course_name ^ "/" redirect *) @@ -51,6 +53,11 @@ let is_valid_course name = let pth = Shared.course_dir ^ name in (is_safe_path name && is_directory pth) +let is_valid_page course_name page_name = + let pth = Shared.course_dir ^ course_name ^ "/" ^ page_name in + (is_safe_path course_name && is_safe_path page_name && is_file pth) + + let routes = [ Dream.get "/course/:course_name/" (fun request -> let name = get_course_name request in @@ -63,16 +70,18 @@ let routes = [ ); Dream.get "/course/:course_name/page/:page_name" (fun request -> - let name = get_course_name request in - if is_valid_course name then - Dream.html @@ Render.render_sidebar @@ Render.render_page name (if is_safe_path (Dream.param request "page_name") then (Dream.param request "page_name") else "") - + let course_name = get_course_name request in + let page_name = get_page_name request in + if is_valid_course course_name then + if is_valid_page course_name page_name then + Dream.html @@ Render.render_sidebar @@ Render.render_page course_name page_name else Dream.empty `Not_Found + else + Dream.empty `Not_Found ); - Dream.get "/static/**" (Dream.static "./static"); Dream.get "/" (fun _ -> Dream.html (Render.render_sidebar @@ Render.render_course_list)); Dream.get "/robots.txt" (Dream.from_filesystem "./static" "robots.txt"); diff --git a/learning/test/test_server.ml b/learning/test/test_server.ml @@ -13,13 +13,13 @@ let test_server = Dream.test @@ Dream.router Server.routes - let root_response = test_server (Dream.request ~target:"/" "") let course_0_response = test_server (Dream.request ~target:"/course/course_0/" "") let course_1_response = test_server (Dream.request ~target:"/course/course_1/" "") +let course_0_page_0_response = test_server (Dream.request ~target:"/course/course_0/page/0_example.sl" "") let course_dne_response = test_server (Dream.request ~target:"/course/this_course_doesnt_exist/" "") - - +let course_dne_page_dne_response = test_server (Dream.request ~target:"/course/this_course_doesnt_exist/page/this_page_doesnt_exist.sl" "") +let page_dne_response = test_server (Dream.request ~target:"/course/course_0/page/this_page_doesnt_exist.sl" "") let test_server () = assert (not (Server.is_safe_path "../")); @@ -36,3 +36,6 @@ let test_server () = assert (Dream.status_to_int (Dream.status course_0_response) = 200); assert (Dream.status_to_int (Dream.status course_1_response) = 200); assert (Dream.status_to_int (Dream.status course_dne_response) = 404); + assert (Dream.status_to_int (Dream.status course_dne_page_dne_response) = 404); + assert (Dream.status_to_int (Dream.status page_dne_response) = 404); + assert (Dream.status_to_int (Dream.status course_0_page_0_response) = 200);