From ec67aebfdad630d35d3129d0ac9af58d9e8ea680 Mon Sep 17 00:00:00 2001 From: Paul Berg Date: Mon, 5 Sep 2022 16:05:10 +0200 Subject: [PATCH] Update to Pluto 0.19.10 & HTTP 1.0 (#79) Co-authored-by: Fons van der Plas --- Project.toml | 7 +- src/Export.jl | 2 +- src/HTTPRouter.jl | 28 +++++--- src/PlutoSliderServer.jl | 73 +++++++++----------- test/{connections.jl => Bond connections.jl} | 0 test/{filewatching.jl => Folder watching.jl} | 31 ++++----- test/{staterequest.jl => HTTP requests.jl} | 25 +++---- test/plutohash.jl | 2 +- test/runtests.jl | 6 +- test/runtestserver.jl | 1 + test/static export.jl | 10 +-- 11 files changed, 88 insertions(+), 97 deletions(-) rename test/{connections.jl => Bond connections.jl} (100%) rename test/{filewatching.jl => Folder watching.jl} (91%) rename test/{staterequest.jl => HTTP requests.jl} (86%) diff --git a/Project.toml b/Project.toml index cc6bea0..463600f 100644 --- a/Project.toml +++ b/Project.toml @@ -30,14 +30,15 @@ Configurations = "0.16, 0.17" FromFile = "0.1" Git = "1" GitHubActions = "0.1" -HTTP = "^0.9.3" +HTTP = "^1.0.2" JSON = "0.21" -Pluto = "0.19.5" +Pluto = "0.19.10" TerminalLoggers = "0.1" julia = "1.6" [extras] +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["Test"] +test = ["Test", "Random"] diff --git a/src/Export.jl b/src/Export.jl index 616ecec..a85f743 100644 --- a/src/Export.jl +++ b/src/Export.jl @@ -78,7 +78,7 @@ function try_get_exact_pluto_version() catch e if get(ENV, "HIDE_PLUTO_EXACT_VERSION_WARNING", "false") == "false" @error "Failed to get exact Pluto version from dependency. Your website is not guaranteed to work forever." exception = - (e, catch_backtrace()) + (e, catch_backtrace()) maxlog = 1 end Pluto.PLUTO_VERSION end diff --git a/src/HTTPRouter.jl b/src/HTTPRouter.jl index 9d97a17..a0b6766 100644 --- a/src/HTTPRouter.jl +++ b/src/HTTPRouter.jl @@ -192,7 +192,7 @@ function make_router( end end - HTTP.@register( + HTTP.register!( router, "GET", "/", @@ -217,11 +217,11 @@ function make_router( end |> with_cors! |> with_not_cacheable! - end + end, ) - HTTP.@register( + HTTP.register!( router, "GET", "/pluto_export.json", @@ -230,15 +230,15 @@ function make_router( with_json! |> with_cors! |> with_not_cacheable! - end + end, ) # !!!! IDEAAAA also have a get endpoint with the same thing but the bond data is base64 encoded in the URL # only use it when the amount of data is not too much :o - HTTP.@register(router, "POST", "/staterequest/*/", serve_staterequest) - HTTP.@register(router, "GET", "/staterequest/*/*", serve_staterequest) - HTTP.@register(router, "GET", "/bondconnections/*/", serve_bondconnections) + HTTP.register!(router, "POST", "/staterequest/*/", serve_staterequest) + HTTP.register!(router, "GET", "/staterequest/*/*", serve_staterequest) + HTTP.register!(router, "GET", "/bondconnections/*/", serve_bondconnections) if static_dir !== nothing function serve_pluto_asset(request::HTTP.Request) @@ -250,14 +250,14 @@ function make_router( ) Pluto.asset_response(filepath) end - HTTP.@register(router, "GET", "/pluto_asset/*", serve_pluto_asset) + HTTP.register!(router, "GET", "/pluto_asset/*", serve_pluto_asset) function serve_asset(request::HTTP.Request) uri = HTTP.URI(request.target) filepath = joinpath(static_dir, relpath(HTTP.unescapeuri(uri.path), "/")) Pluto.asset_response(filepath) end - HTTP.@register(router, "GET", "/*", serve_asset) + HTTP.register!(router, "GET", "/*", serve_asset) end router @@ -294,6 +294,14 @@ function with_cacheable!(response::HTTP.Response) end function with_not_cacheable!(response::HTTP.Response) - push!(response.headers, "Cache-Control" => "no-store, no-cache, max-age=5") + push!(response.headers, "Cache-Control" => "no-store, no-cache") response end + +function ReferrerMiddleware(handler) + return function (req::HTTP.Request) + response = handler(req) + push!(response.headers, "Referrer-Policy" => "origin-when-cross-origin") + return response + end +end diff --git a/src/PlutoSliderServer.jl b/src/PlutoSliderServer.jl index 939f2bb..647f4a3 100644 --- a/src/PlutoSliderServer.jl +++ b/src/PlutoSliderServer.jl @@ -15,7 +15,7 @@ using FromFile @from "./ConfigurationDocs.jl" import @extract_docs, get_kwdocs, list_options_md, list_options_toml @from "./ReloadFolder.jl" import update_sessions!, select -@from "./HTTPRouter.jl" import make_router +@from "./HTTPRouter.jl" import make_router, ReferrerMiddleware @from "./gitpull.jl" import fetch_pull @from "./PlutoHash.jl" import plutohash, base64urlencode, base64urldecode @@ -48,7 +48,9 @@ function load_cool_logger() logger_loaded[] = true if ((global_logger() isa ConsoleLogger) && !is_inside_pluto()) if get(ENV, "GITHUB_ACTIONS", "false") == "true" - global_logger(GitHubActionsLogger()) + # TODO: disabled because of https://github.com/JuliaWeb/HTTP.jl/issues/921 + + # global_logger(GitHubActionsLogger()) else global_logger(try TerminalLogger(; margin=1) @@ -272,39 +274,17 @@ function run_directory( @info "# Starting server..." address - # This is boilerplate HTTP code, don't read it # We start the HTTP server before launching notebooks so that the server responds to heroku/digitalocean garbage fast enough - http_server_task = @async HTTP.serve( + http_server = HTTP.serve!( + router |> ReferrerMiddleware, hostIP, UInt16(port), - stream=true, server=serversocket, - ) do http::HTTP.Stream - request::HTTP.Request = http.message - request.body = read(http) - HTTP.closeread(http) - - params = HTTP.queryparams(HTTP.URI(request.target)) - - response_body = Base.invokelatest(HTTP.handle, router, request) - - request.response::HTTP.Response = response_body - request.response.request = request - try - HTTP.setheader(http, "Referrer-Policy" => "origin-when-cross-origin") - HTTP.startwrite(http) - write(http, request.response.body) - HTTP.closewrite(http) - catch e - if isa(e, Base.IOError) || isa(e, ArgumentError) - # @warn "Attempted to write to a closed stream at $(request.target)" - else - rethrow(e) - end - end - end + ) + + @info "# Server started" else - http_server_task = @async 1 + 1 + http_server = nothing serversocket = nothing end @@ -406,20 +386,31 @@ function run_directory( watch_folder(debounced, start_dir) end - if should_watch - # todo: skip first watch_folder so that we dont need this sleepo - sleep(2) - end - on_ready((; serversocket, server_session, notebook_sessions)) + if http_server === nothing + on_ready((; serversocket, http_server, server_session, notebook_sessions)) + else + try + if should_watch + # todo: skip first watch_folder so that we dont need this sleepo (EDIT: i forgot why this sleep is here.. oops!) + sleep(2) + end + on_ready((; serversocket, http_server, server_session, notebook_sessions)) - try - wait(http_server_task) - catch e - @ignorefailure close(serversocket) - @ignorefailure schedule(watch_dir_task, e; error=true) - e isa InterruptException || rethrow(e) + # blocking call, waiting for a Ctrl-C interrupt + wait(http_server) + catch e + @info "# Closing web server..." + @ignorefailure close(http_server) + if should_watch + @info "Stopping directory watching..." + istaskdone(watch_dir_task) || + @ignorefailure schedule(watch_dir_task, e; error=true) + end + e isa InterruptException || rethrow(e) + @info "Server exited ✅" + end end end diff --git a/test/connections.jl b/test/Bond connections.jl similarity index 100% rename from test/connections.jl rename to test/Bond connections.jl diff --git a/test/filewatching.jl b/test/Folder watching.jl similarity index 91% rename from test/filewatching.jl rename to test/Folder watching.jl index eeadd07..679101e 100644 --- a/test/filewatching.jl +++ b/test/Folder watching.jl @@ -37,8 +37,7 @@ function cp_nb_with_tweaks(from::String, to::String) end @testset "Folder watching" begin - test_dir = tempname(cleanup=false) - mkdir(test_dir) + test_dir = mktempdir(cleanup=false) try # open the folder on macos: @@ -52,6 +51,7 @@ end cp_nb_with_tweaks(joinpath(@__DIR__, p), joinpath(test_dir, p)) end + Random.seed!(time_ns()) port = rand(12345:65000) @@ -62,22 +62,14 @@ end still_booting[] = false end - t = Pluto.@asynclog begin - try - PlutoSliderServer.run_directory( - test_dir; - Export_enabled=false, - Export_output_dir=test_dir, - SliderServer_port=port, - SliderServer_watch_dir=true, - on_ready, - ) - catch e - if !(e isa TaskFailedException) - showerror(stderr, e, stacktrace(catch_backtrace())) - end - end - end + t = Pluto.@asynclog PlutoSliderServer.run_directory( + test_dir; + Export_enabled=false, + Export_output_dir=test_dir, + SliderServer_port=port, + SliderServer_watch_dir=true, + on_ready, + ) while still_booting[] @@ -92,6 +84,7 @@ end json_nbs() = index_json()["notebooks"] |> keys |> collect + @test length(notebook_sessions) == 1 @test json_nbs() == ["basic2.jl"] @test index_json()["notebooks"]["basic2.jl"]["frontmatter"]["title"] == "Pancakes" @@ -247,7 +240,7 @@ end end sleep(2) - close(ready_result[].serversocket) + close(ready_result[].http_server) try wait(t) diff --git a/test/staterequest.jl b/test/HTTP requests.jl similarity index 86% rename from test/staterequest.jl rename to test/HTTP requests.jl index 0fc4a1e..ef7f083 100644 --- a/test/staterequest.jl +++ b/test/HTTP requests.jl @@ -3,9 +3,10 @@ import PlutoSliderServer.Pluto import PlutoSliderServer.HTTP using Test -using UUIDs +using UUIDs, Random @testset "HTTP requests" begin + Random.seed!(time_ns()) test_dir = tempname(cleanup=false) cp(@__DIR__, test_dir) @@ -22,19 +23,13 @@ using UUIDs end t = Pluto.@asynclog begin - try - PlutoSliderServer.run_directory( - test_dir; - Export_enabled=false, - SliderServer_port=port, - notebook_paths, - on_ready, - ) - catch e - if !(e isa TaskFailedException) - showerror(stderr, e, stacktrace(catch_backtrace())) - end - end + PlutoSliderServer.run_directory( + test_dir; + Export_enabled=false, + SliderServer_port=port, + notebook_paths, + on_ready, + ) end @@ -110,7 +105,7 @@ using UUIDs end end - close(ready_result[].serversocket) + close(ready_result[].http_server) try wait(t) diff --git a/test/plutohash.jl b/test/plutohash.jl index 183fdc1..e07e591 100644 --- a/test/plutohash.jl +++ b/test/plutohash.jl @@ -2,7 +2,7 @@ using Test import PlutoSliderServer: plutohash, base64urlencode, base64urldecode import HTTP -@testset "PlutoHash" begin +@testset "plutohash" begin @test plutohash("Hannes") == "OI48wVWerxEEnz5lIj6CPPRB8NOwwba-LkFYTDp4aUU" @test base64urlencode(UInt8[0, 0, 63, 0, 0, 62, 42]) == "AAA_AAA-Kg" diff --git a/test/runtests.jl b/test/runtests.jl index 797c9b3..697d6cf 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -18,7 +18,7 @@ else include("./plutohash.jl") include("./configuration.jl") include("./static export.jl") - include("./staterequest.jl") - include("./filewatching.jl") - include("./connections.jl") + include("./HTTP requests.jl") + include("./Folder watching.jl") + include("./Bond connections.jl") end \ No newline at end of file diff --git a/test/runtestserver.jl b/test/runtestserver.jl index 4b0dd9c..40040d3 100644 --- a/test/runtestserver.jl +++ b/test/runtestserver.jl @@ -2,6 +2,7 @@ using PlutoSliderServer ENV["JULIA_DEBUG"] = PlutoSliderServer +Random.seed!(time_ns()) test_dir = tempname(cleanup=false) cp(@__DIR__, test_dir) diff --git a/test/static export.jl b/test/static export.jl index 1911829..9aaac33 100644 --- a/test/static export.jl +++ b/test/static export.jl @@ -4,10 +4,12 @@ using Test using Logging import JSON import Pluto: without_pluto_file_extension +import Random original_dir1 = joinpath(@__DIR__, "dir1") make_test_dir() = let + Random.seed!(time_ns()) new = tempname(cleanup=false) cp(original_dir1, new) new @@ -15,7 +17,7 @@ make_test_dir() = cache_dir = tempname(cleanup=false) -@testset "Basic github action" begin +@testset "static - Basic github action" begin test_dir = make_test_dir() @show test_dir cache_dir @@ -60,7 +62,7 @@ cache_dir = tempname(cleanup=false) end -@testset "Separate state & notebook files" begin +@testset "static - Separate state & notebook files" begin test_dir = make_test_dir() @show test_dir cd(test_dir) @@ -112,7 +114,7 @@ end @test occursin("appelsap", read("a.html", String)) end -@testset "Single notebook" begin +@testset "static - Single notebook" begin test_dir = make_test_dir() # @show test_dir cache_dir @@ -136,7 +138,7 @@ end end -@testset "Index HTML and JSON" begin +@testset "static - Index HTML and JSON" begin test_dir = make_test_dir() @show test_dir cache_dir