forked from caddyserver/caddy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
middleware.go
132 lines (112 loc) · 5.32 KB
/
middleware.go
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Package middleware provides some types and functions common among middleware.
package middleware
import "net/http"
type (
// Generator represents the outer layer of a middleware that
// parses tokens to configure the middleware instance.
//
// Note: This type will be moved into a different package in the future.
Generator func(Controller) (Middleware, error)
// Middleware is the middle layer which represents the traditional
// idea of middleware: it chains one Handler to the next by being
// passed the next Handler in the chain.
//
// Note: This type will be moved into a different package in the future.
Middleware func(Handler) Handler
// Handler is like http.Handler except ServeHTTP returns a status code
// and an error. The status code is for the client's benefit; the error
// value is for the server's benefit. The status code will be sent to
// the client while the error value will be logged privately. Sometimes,
// an error status code (4xx or 5xx) may be returned with a nil error
// when there is no reason to log the error on the server.
//
// If a HandlerFunc returns an error (status >= 400), it should NOT
// write to the response. This philosophy makes middleware.Handler
// different from http.Handler: error handling should happen at the
// application layer or in dedicated error-handling middleware only
// rather than with an "every middleware for itself" paradigm.
//
// The application or error-handling middleware should incorporate logic
// to ensure that the client always gets a proper response according to
// the status code. For security reasons, it should probably not reveal
// the actual error message. (Instead it should be logged, for example.)
//
// Handlers which do write to the response should return a status value
// < 400 as a signal that a response has been written. In other words,
// only error-handling middleware or the application will write to the
// response for a status code >= 400. When ANY handler writes to the
// response, it should return a status code < 400 to signal others to
// NOT write to the response again, which would be erroneous.
Handler interface {
ServeHTTP(http.ResponseWriter, *http.Request) (int, error)
}
// A Controller provides access to properties of the server. Middleware
// generators use a Controller to construct their instances.
Controller interface {
Dispenser
// Startup registers a function to execute when the server starts.
Startup(func() error)
// Shutdown registers a function to execute when the server exits.
Shutdown(func() error)
// Root returns the file path from which the server is serving.
Root() string
// Context returns the path scope that the Controller is in.
// Note: This is not currently used, but may be in the future.
Context() Path
}
// A Dispenser provides structured access to tokens from a configuration
// file. It dispenses tokens to middleware for parsing so that middleware
// can configure themselves.
Dispenser interface {
// Next loads the next token. Returns true if a token
// was loaded; false otherwise. If false, all tokens
// have already been consumed.
Next() bool
// NextArg loads the next token if it is on the same
// line. Returns true if a token was loaded; false
// otherwise. If false, all tokens on the line have
// been consumed.
NextArg() bool
// NextLine loads the next token only if it is NOT on the same
// line as the current token, and returns true if a token was
// loaded; false otherwise. If false, there is not another token
// or it is on the same line.
NextLine() bool
// NextBlock can be used as the condition of a for loop
// to load the next token as long as it opens a block or
// is already in a block. It returns true if a token was
// loaded, or false when the block's closing curly brace
// was loaded and thus the block ended. Nested blocks are
// not (currently) supported.
NextBlock() bool
// Val gets the text of the current token.
Val() string
// Args is a convenience function that loads the next arguments
// (tokens on the same line) into an arbitrary number of strings
// pointed to in arguments. If there are fewer tokens available
// than string pointers, the remaining strings will not be changed
// and false will be returned. If there were enough tokens available
// to fill the arguments, then true will be returned.
Args(...*string) bool
// RemainingArgs loads any more arguments (tokens on the same line)
// into a slice and returns them. Open curly brace tokens also indicate
// the end of arguments, and the curly brace is not included in
// the return value nor is it loaded.
RemainingArgs() []string
// ArgErr returns an argument error, meaning that another
// argument was expected but not found. In other words,
// a line break, EOF, or open curly brace was encountered instead of
// an argument.
ArgErr() error
// Err generates a custom parse error with a message of msg.
Err(string) error
}
)
// HandlerFunc is a convenience type like http.HandlerFunc, except
// ServeHTTP returns a status code and an error. See Handler
// documentation for more information.
type HandlerFunc func(http.ResponseWriter, *http.Request) (int, error)
// ServeHTTP implements the Handler interface.
func (f HandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
return f(w, r)
}