Skip to content

Documentation: Baked responses via streamhandler must have Vector{UInt8} bodies #1333

Description

@frankier

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions