1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
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)
}
}
|