Middleware
Middleware is a function of the form f(stream::HTTP.Stream, next), where next is the following handler/middleware in the list. It’s called in the order it was added, with the matching handler (if any) called last. By default app.middleware will run on all request methods however you can specify a specific method with app.middleware.get Bellow are examples of common use cases for middleware
Logging
Log each request method and URL.
function log_request(stream, next)
@info "request" stream.message.method stream.message.url
next(stream)
end
# don't forget to register the middleware
app.middleware["**"] = [log_request]Time
The handler below logs the time taken to call the next handlers in the chain.
function time_taken(stream, next)
x = now()
next(stream)
elapsed = now() - x
@info "$(stream.message.target) took $elapsed"
end
# make sure the middleware is first so
# we measure the time of all the downstream handlers
app.middleware["**"] = [time_taken, ...other_middleware]Authentication
For example, authentication might look something like this
function authentication(stream, next)
headers = Bonsai.read(
stream,
Header(x_password=String)
)
if headers.x_password != "secret_password"
return Bonsai.write(stream, Status(403), Body("Forbidden"))
else
next(stream)
end
end
function protected_route(stream, next)
return Bonsai.write(stream, Body("Welcome to the club"))
end
function unproteced_route(stream, next)
return Bonsai.write(stream, Body("Welcome to the club"))
end
function register_middleware!(app)
app.middleware["/protected/**"] = [authentication]
app.get["/protected/"] = protected_route
app.get["/"] = unproteced_route
endTODO: a proper example using JWTs.
CORS
The below middleware will accept CORS requests from any domain and HTTP method. You can restrict it to specific domains by changing the relevant header e.g "Access-Control-Allow_Origin" => "https://my-website.com". For more information on CORS see https://cors-errors.info/
function cors(stream::Stream, next)
res = stream.message.response
if stream.message.method == "OPTIONS"
headers = [
"Access-Control-Allow-Origin" => "*",
"Access-Control-Allow-Headers" => "*",
"Access-Control-Allow-Methods" => "*",
]
for i in headers
HTTP.setheader(res, i)
end
else
headers = [
"Access-Control-Allow-Origin" => "*",
]
for i in headers
HTTP.setheader(res, i)
end
next(stream)
end
end
function register_middleware!(app)
# runs on all routes
app.middleware["**"] = [authentication]
endNote you probably don’t want to use a wildcard * for your origin but rather something more specific.