This example shows some potential confusion when attempting to use baked responses (or otherwise reuse whole response objects).
The pattern works in all cases except for with a string body and a stream response. In this case it will work once, but then the body object, reading a stream of codepoints, will be closed. This is a bit surprising and perhaps should be documented. Additionally, perhaps an exception should be thrown when attempting to send an already closed body. I will prepare a PR for the latter.
#=
Run from the HTTP.jl working copy:
julia --project=. baked_server.jl
Then, for example:
curl -i http://127.0.0.1:8081/string
curl -i http://127.0.0.1:8081/bytes
curl -i http://127.0.0.1:8082/string
curl -i http://127.0.0.1:8082/bytes
=#
module BakedServer
using HTTP
const HANDLER_PORT = 8081
const STREAM_PORT = 8082
const STRING_BODY = "Hello from a baked String body!\n"^32
const BYTES_BODY = Vector{UInt8}(codeunits("Hello from a baked Vector{UInt8} body!\n"^32))
const RESP_STRING = HTTP.Response(200, ["Content-Type" => "text/plain"]; body=STRING_BODY)
const RESP_BYTES = HTTP.Response(200, ["Content-Type" => "text/plain"]; body=BYTES_BODY)
const HANDLER_ROUTER = HTTP.Router()
HTTP.register!(HANDLER_ROUTER, "GET", "/string", req -> RESP_STRING)
HTTP.register!(HANDLER_ROUTER, "GET", "/bytes", req -> RESP_BYTES)
const STREAM_ROUTER = HTTP.Router()
HTTP.register!(STREAM_ROUTER, "GET", "/string", req::HTTP.Request -> RESP_STRING)
HTTP.register!(STREAM_ROUTER, "GET", "/bytes", req::HTTP.Request -> RESP_BYTES)
function start()
handler_server = HTTP.serve!(HANDLER_ROUTER, "127.0.0.1", HANDLER_PORT)
stream_server = HTTP.listen!(HTTP.streamhandler(STREAM_ROUTER), "127.0.0.1", STREAM_PORT)
@info "request-handler server listening on http://127.0.0.1:$HANDLER_PORT (/string, /bytes)"
@info "stream-handler server listening on http://127.0.0.1:$STREAM_PORT (/string, /bytes)"
return handler_server, stream_server
end
end
if abspath(PROGRAM_FILE) == @__FILE__
handler_server, stream_server = BakedServer.start()
try
wait(handler_server)
catch e
e isa InterruptException || rethrow()
finally
close(handler_server)
close(stream_server)
end
end
This example shows some potential confusion when attempting to use baked responses (or otherwise reuse whole response objects).
The pattern works in all cases except for with a string body and a stream response. In this case it will work once, but then the body object, reading a stream of codepoints, will be closed. This is a bit surprising and perhaps should be documented. Additionally, perhaps an exception should be thrown when attempting to send an already closed body. I will prepare a PR for the latter.