55 lines
1.7 KiB
Go
55 lines
1.7 KiB
Go
package gemini
|
|
|
|
import "context"
|
|
|
|
// Handler is a function which can turn a gemini request into a gemini response.
|
|
//
|
|
// A Handler MUST NOT return a nil response. Errors should be returned in the form
|
|
// of error responses (4x, 5x, 6x response status). If the Handler should not be
|
|
// responsible for the requested resource it can return a 51 response.
|
|
type Handler func(context.Context, *Request) *Response
|
|
|
|
// Middleware is a handle decorator.
|
|
//
|
|
// It returns a handler which may call the passed-in handler or not, or may
|
|
// transform the request or response in some way.
|
|
type Middleware func(Handler) Handler
|
|
|
|
// FallthroughHandler builds a handler which tries multiple child handlers.
|
|
//
|
|
// The returned handler will invoke each of the passed child handlers in order,
|
|
// stopping when it receives a response with status other than 51.
|
|
func FallthroughHandler(handlers ...Handler) Handler {
|
|
return func(ctx context.Context, req *Request) *Response {
|
|
for _, handler := range handlers {
|
|
response := handler(ctx, req)
|
|
if response.Status != StatusNotFound {
|
|
return response
|
|
}
|
|
}
|
|
|
|
return NotFound("Resource does not exist.")
|
|
}
|
|
}
|
|
|
|
// Filter wraps a handler with a predicate which determines whether to run the handler.
|
|
//
|
|
// When the predicate function returns false, the Filter returns the provided failure
|
|
// response. The failure argument may be nil, in which case a "51 Resource does not exist."
|
|
// response will be used.
|
|
func Filter(
|
|
predicate func(context.Context, *Request) bool,
|
|
handler Handler,
|
|
failure *Response,
|
|
) Handler {
|
|
if failure == nil {
|
|
failure = NotFound("Resource does not exist.")
|
|
}
|
|
return func(ctx context.Context, req *Request) *Response {
|
|
if !predicate(ctx, req) {
|
|
return failure
|
|
}
|
|
return handler(ctx, req)
|
|
}
|
|
}
|