diff --git a/examples/dune b/examples/dune index db8d0451..9251f5b5 100644 --- a/examples/dune +++ b/examples/dune @@ -30,19 +30,19 @@ (rule (targets test_output.txt) - (deps (:script ./run_test.sh) ./sse_client.exe ./sse_server.exe) + (deps (:script ./run_test.sh) ./sse_client.exe (:server ./sse_server.exe)) (enabled_if (= %{system} "linux")) (package tiny_httpd) (action - (with-stdout-to %{targets} (run %{script} 8082)))) + (with-stdout-to %{targets} (run %{script} %{server} 8082)))) (rule (targets test_output_domains.txt) - (deps (:script ./run_test.sh) ./sse_client.exe ./sse_server_domains.exe) + (deps (:script ./run_test.sh) ./sse_client.exe (:server ./sse_server_domains.exe)) (enabled_if (and (= %{system} "linux") (>= %{ocaml_version} 5.0.0))) (package tiny_httpd) (action - (with-stdout-to %{targets} (run %{script} 8083)))) + (with-stdout-to %{targets} (run %{script} %{server} 8083)))) (rule (alias runtest) diff --git a/examples/run_test.sh b/examples/run_test.sh index f4d81dfa..484407fc 100755 --- a/examples/run_test.sh +++ b/examples/run_test.sh @@ -1,8 +1,9 @@ #!/usr/bin/env bash -PORT=$1 +SERVER=$1 +PORT=$2 -./sse_server.exe -p $PORT & +./$SERVER -p $PORT & PID=$! sleep 0.1 diff --git a/src/bin/dune b/src/bin/dune index 938770d9..2966647a 100644 --- a/src/bin/dune +++ b/src/bin/dune @@ -7,6 +7,15 @@ (flags :standard -warn-error -3) (libraries tiny_httpd)) +(executable + (name http_of_dir_domains) + (public_name http_of_dir_domains) + (enabled_if (>= %{ocaml_version} 5.0.0)) + (package tiny_httpd_domains) + (modules http_of_dir_domains) + (flags :standard -warn-error -3) + (libraries tiny_httpd tiny_httpd_domains)) + (executable (name vfs_pack) (public_name tiny-httpd-vfs-pack) diff --git a/src/bin/http_of_dir_domains.ml b/src/bin/http_of_dir_domains.ml new file mode 100644 index 00000000..55b38152 --- /dev/null +++ b/src/bin/http_of_dir_domains.ml @@ -0,0 +1,62 @@ +module S = Tiny_httpd +module U = Tiny_httpd_util +module D = Tiny_httpd_dir +module Pf = Printf +module Do = Tiny_httpd_domains + +let serve ~config pool new_thread (dir:string) addr port j : _ result = + let server = S.create ~new_thread ~max_connections:j ~addr ~port () in + Printf.printf "serve directory %s on http://%(%s%):%d\n%!" + dir (if S.is_ipv6 server then "[%s]" else "%s") addr port; + + D.add_dir_path ~config ~dir ~prefix:"" server; + Do.run pool server + +let parse_size s : int = + try Scanf.sscanf s "%dM" (fun n -> n * 1_024 * 1_024) + with _ -> + try Scanf.sscanf s "%dk" (fun n -> n * 1_024) + with _ -> + try int_of_string s + with _ -> raise (Arg.Bad "invalid size (expected [kM]?)") + +let main () = + let config = + D.config ~dir_behavior:Index_or_lists () + in + let dir_ = ref "." in + let addr = ref "127.0.0.1" in + let port = ref 8080 in + let j = ref 32 in + let nbd = ref (Domain.recommended_domain_count ()) in + + Arg.parse (Arg.align [ + "--addr", Set_string addr, " address to listen on"; + "-a", Set_string addr, " alias to --listen"; + "--port", Set_int port, " port to listen on"; + "-p", Set_int port, " alias to --port"; + "-n", Arg.Set_int nbd, " set number of domains"; + "--dir", Set_string dir_, " directory to serve (default: \".\")"; + "--debug", Unit (fun () -> S._enable_debug true), " debug mode"; + "--upload", Unit (fun () -> config.upload <- true), " enable file uploading"; + "--no-upload", Unit (fun () -> config.upload <- false), " disable file uploading"; + "--download", Unit (fun () -> config.download <- true), " enable file downloading"; + "--no-download", Unit (fun () -> config.download <- false), " disable file downloading"; + "--max-upload", String (fun i -> config.max_upload_size <- parse_size i), + " maximum size of files that can be uploaded"; + "--auto-index", + Bool (fun b -> config.dir_behavior <- + (if b then Index_or_lists else Lists)), + " automatically redirect to index.html if present"; + "--delete", Unit (fun () -> config.delete <- true), " enable `delete` on files"; + "--no-delete", Unit (fun () -> config.delete <- false), " disable `delete` on files"; + "-j", Set_int j, " maximum number of simultaneous connections"; + ]) (fun s -> dir_ := s) "http_of_dir [options] [dir]"; + let pool = Domainslib.Task.setup_pool ~num_domains:!nbd () in + let new_thread = Do.new_thread pool in + match serve ~config pool new_thread !dir_ !addr !port !j with + | Ok () -> () + | Error e -> + raise e + +let () = main () diff --git a/tests/dl-out-domains.expect b/tests/dl-out-domains.expect new file mode 100644 index 00000000..a203a55d --- /dev/null +++ b/tests/dl-out-domains.expect @@ -0,0 +1,5 @@ +serve directory . on http://127.0.0.1:8098 + 0 0 52428800 data21 + 0 0 52428800 data22 + 0 0 52428800 data23 + 0 0 157286400 total diff --git a/tests/download_chunked.sh b/tests/download_chunked.sh index 5ee1e1b2..8035972e 100755 --- a/tests/download_chunked.sh +++ b/tests/download_chunked.sh @@ -1,21 +1,22 @@ #!/usr/bin/env sh SERVER=$1 -PORT=8088 +PORT=$2 + "$SERVER" . -p $PORT & PID=$! sleep 0.1 -echo download1 1>&2 +echo === download1 $SERVER $PORT 1>&2 curl -N "http://localhost:${PORT}/foo_50" -o data21 \ -H 'Tranfer-encoding: chunked' --max-time 10 -echo download2 1>&2 +echo === download2 $SERVER $PORT 1>&2 curl -N "http://localhost:${PORT}/foo_50" -o data22 \ -H 'Tranfer-encoding: chunked' --max-time 10 -echo download3 1>&2 +echo === download3 $SERVER $PORT 1>&2 curl -N "http://localhost:${PORT}/foo_50" -o data23 \ -H 'Tranfer-encoding: chunked' --max-time 10 diff --git a/tests/dune b/tests/dune index 005f360b..eb1f34a5 100644 --- a/tests/dune +++ b/tests/dune @@ -1,4 +1,4 @@ - +;echo (rule (targets echo1.out) (deps (:bin ../examples/echo.exe)) @@ -7,6 +7,68 @@ (package tiny_httpd_camlzip) (action (with-stdout-to %{targets} (run ./echo1.sh %{bin} 8085)))) +(rule + (alias runtest) + (package tiny_httpd_camlzip) + (enabled_if (= %{system} "linux")) + (action (diff echo1.expect echo1.out))) + +;sse_count +(rule + (targets sse_count.out) + (deps (:bin ../examples/sse_server.exe)) + (locks /port) + (enabled_if (= %{system} "linux")) + (package tiny_httpd) + (action (with-stdout-to %{targets} (run ./sse_count.sh %{bin} 8086)))) + +(rule + (alias runtest) + (package tiny_httpd) + (enabled_if (= %{system} "linux")) + (action (diff sse_count.expect sse_count.out))) + +;upload +(rule + (targets upload-out) + (deps (:bin ../src/bin/http_of_dir.exe) foo_50) + (locks /port) + (package tiny_httpd) + (enabled_if (= %{system} "linux")) + (action (with-stdout-to %{targets} + (run ./upload_chunked.sh %{bin} 8087)))) + +(rule + (alias runtest) + (package tiny_httpd) + (enabled_if (= %{system} "linux")) + (action (diff upload-out.expect upload-out))) + +;download +(rule + (targets dl-out) + (deps (:bin ../src/bin/http_of_dir.exe) foo_50) + (locks /port) + (package tiny_httpd) + (enabled_if (= %{system} "linux")) + (action (with-stdout-to %{targets} + (run ./download_chunked.sh %{bin} 8088)))) + +(rule + (alias runtest) + (package tiny_httpd) + (enabled_if (= %{system} "linux")) + (action (diff dl-out.expect dl-out))) + +;big file (50Mo) +(rule + (targets foo_50) + (enabled_if (= %{system} "linux")) + (action + (bash "dd if=/dev/zero of=%{targets} bs=1M count=50"))) + +; with domains +;echo (rule (targets echo1_domains.out) (deps (:bin ../examples/echo_domains.exe)) @@ -17,24 +79,11 @@ (rule (alias runtest) - (package tiny_httpd_camlzip) - (enabled_if (= %{system} "linux")) - (action (diff echo1.expect echo1.out))) - -(rule - (alias runtest) - (package tiny_httpd_camlzip) + (package tiny_httpd_domains) (enabled_if (and (= %{system} "linux") (>= %{ocaml_version} 5.0.0))) (action (diff echo1_domains.expect echo1_domains.out))) -(rule - (targets sse_count.out) - (deps (:bin ../examples/sse_server.exe)) - (locks /port) - (enabled_if (= %{system} "linux")) - (package tiny_httpd) - (action (with-stdout-to %{targets} (run ./sse_count.sh %{bin} 8086)))) - +;sse_count (rule (targets sse_count_domains.out) (deps (:bin ../examples/sse_server_domains.exe)) @@ -46,41 +95,37 @@ (rule (alias runtest) (package tiny_httpd) - (enabled_if (= %{system} "linux")) + (enabled_if (and (= %{system} "linux") (>= %{ocaml_version} 5.0.0))) (action (diff sse_count_domains.expect sse_count_domains.out))) +;upload (rule - (targets upload-out) - (deps (:bin ../src/bin/http_of_dir.exe) foo_50) + (targets upload-out-domains) + (deps (:bin ../src/bin/http_of_dir_domains.exe) foo_50) (locks /port) - (package tiny_httpd) - (enabled_if (= %{system} "linux")) + (package tiny_httpd_domains) + (enabled_if (and (= %{system} "linux") (>= %{ocaml_version} 5.0.0))) (action (with-stdout-to %{targets} - (run ./upload_chunked.sh %{bin})))) + (run ./upload_chunked.sh %{bin} 8097)))) (rule (alias runtest) (package tiny_httpd) - (enabled_if (= %{system} "linux")) - (action (diff upload-out.expect upload-out))) + (enabled_if (and (= %{system} "linux") (>= %{ocaml_version} 5.0.0))) + (action (diff upload-out-domains.expect upload-out-domains))) +;download (rule - (targets dl-out) - (deps (:bin ../src/bin/http_of_dir.exe) foo_50) + (targets dl-out-domains) + (deps (:bin ../src/bin/http_of_dir_domains.exe) foo_50) (locks /port) - (package tiny_httpd) - (enabled_if (= %{system} "linux")) + (package tiny_httpd_domains) + (enabled_if (and (= %{system} "linux") (>= %{ocaml_version} 5.0.0))) (action (with-stdout-to %{targets} - (run ./download_chunked.sh %{bin})))) + (run ./download_chunked.sh %{bin} 8098)))) (rule (alias runtest) - (package tiny_httpd) - (enabled_if (= %{system} "linux")) - (action (diff dl-out.expect dl-out))) - -(rule - (targets foo_50) - (enabled_if (= %{system} "linux")) - (action - (bash "dd if=/dev/zero of=%{targets} bs=1M count=50"))) + (package tiny_httpd_domains) + (enabled_if (and (= %{system} "linux") (>= %{ocaml_version} 5.0.0))) + (action (diff dl-out-domains.expect dl-out-domains))) diff --git a/tests/echo1.sh b/tests/echo1.sh index c1e0dbcb..78b35e59 100755 --- a/tests/echo1.sh +++ b/tests/echo1.sh @@ -6,15 +6,20 @@ PORT=$2 "$ECHO" -p $PORT & PID=$! sleep 0.1 + +echo === echo $ECHO $PORT 1>&2 curl -N "http://localhost:${PORT}/echo/?a=b&c=d" -H user-agent:test --max-time 5 sleep 0.1 +echo === echo $ECHO $PORT 1>&2 curl -N "http://localhost:${PORT}/vfs/" --max-time 5 sleep 0.1 +echo === echo $ECHO $PORT 1>&2 curl -N "http://localhost:${PORT}/vfs/a.txt" --max-time 5 sleep 0.1 +echo === echo $ECHO $PORT 1>&2 curl -N "http://localhost:${PORT}/vfs/sub/yolo.html" --max-time 5 kill $PID diff --git a/tests/sse_count.sh b/tests/sse_count.sh index fdca1325..f5318d3f 100755 --- a/tests/sse_count.sh +++ b/tests/sse_count.sh @@ -7,5 +7,6 @@ PORT=$2 PID=$! sleep 0.1 +echo === sse_count $SSE_SERVER $PORT 1>&2 curl -N "http://localhost:${PORT}/count/10" -H user-agent:test --max-time 10 kill $PID diff --git a/tests/upload-out-domains.expect b/tests/upload-out-domains.expect new file mode 100644 index 00000000..76f6a08c --- /dev/null +++ b/tests/upload-out-domains.expect @@ -0,0 +1,2 @@ +serve directory . on http://127.0.0.1:8097 +upload successful 0 0 52428800 data diff --git a/tests/upload_chunked.sh b/tests/upload_chunked.sh index 5afebaca..ddec568e 100755 --- a/tests/upload_chunked.sh +++ b/tests/upload_chunked.sh @@ -3,13 +3,14 @@ if [ -f data ]; then rm data ; fi SERVER=$1 -PORT=8087 +PORT=$2 "$SERVER" . -p $PORT --upload --max-upload 100000000000 & PID=$! sleep 0.1 +echo === upload $SERVER $PORT 1>&2 cat foo_50 | curl -N -X PUT http://localhost:$PORT/data --data-binary @- \ -H 'Transfer-Encoding: chunked' --max-time 10