Documentation ¶
Overview ¶
Package garcon is a server for API and static website including middlewares to manage rate-limit, Cookies, JWT, CORS, OPA, web traffic, Prometheus export and PProf.
Package reqlog logs incoming request URL and browser fingerprint.
Index ¶
- Constants
- Variables
- func AppendPrefixes(origins []string, prefixes ...string) []string
- func AppendURLs(urls []*url.URL, prefixes ...*url.URL) []*url.URL
- func CORSHandler(origins []string, debug bool) func(next http.Handler) http.Handler
- func ConvertSize(sizeInBytes int) string
- func ConvertSize64(sizeInBytes int64) string
- func FingerprintMD(r *http.Request) string
- func InsertSchema(origins []string)
- func InvalidPath(w http.ResponseWriter, r *http.Request)
- func LoadPolicy(filenames []string) (*ast.Compiler, error)
- func LogRequest(next http.Handler) http.Handler
- func LogRequestFingerprint(next http.Handler) http.Handler
- func NewHash() (hash.Hash, error)
- func NotImplemented(w http.ResponseWriter, r *http.Request)
- func Obfuscate(str string) (string, error)
- func OriginsFromURLs(urls []*url.URL) []string
- func ParseURLs(origins []string) []*url.URL
- func PrintVersion(v string)
- func Printable(s string) int
- func PrintableRune(r rune) bool
- func Printables(array []string) int
- func ProbeCPU() interface{ ... }
- func RejectInvalidURI(next http.Handler) http.Handler
- func SafeHeader(r *http.Request, header string) string
- func Sanitize(str string) string
- func ServerHeader(version string) func(next http.Handler) http.Handler
- func SetVersionFlag(fs *flag.FlagSet, flagName, v string)
- func SplitClean(values string) []string
- func StartPProfServer(port int)
- func TraversalPath(w http.ResponseWriter, r *http.Request) bool
- func Value(r *http.Request, key, header string) (string, error)
- func Values(r *http.Request, key string) ([]string, error)
- func Version(program, vvv string) string
- func WriteJSONErr(w http.ResponseWriter, r *http.Request, statusCode int, a ...any)
- type Chain
- type Checker
- type ErrWriter
- func (errWriter ErrWriter) InvalidPath(w http.ResponseWriter, r *http.Request)
- func (errWriter ErrWriter) NotImplemented(w http.ResponseWriter, r *http.Request)
- func (errWriter ErrWriter) Write(w http.ResponseWriter, r *http.Request, statusCode int, messages ...any)
- func (errWriter ErrWriter) WriteSafeJSONErr(w http.ResponseWriter, r *http.Request, statusCode int, messages ...any)
- type Garcon
- type Middleware
- type Option
- func WithDev(enable ...bool) Option
- func WithDocURL(docURL string) Option
- func WithIncorruptible(secretKeyHex string, expiry time.Duration, setIP bool) Option
- func WithJWT(secretKeyHex string, planPerm ...any) Option
- func WithLimiter(values ...int) Option
- func WithOPA(opaFilenames ...string) Option
- func WithPProf(port int) Option
- func WithProm(port int, namespace string) Option
- func WithReqLogs(verbosity ...int) Option
- func WithServerHeader(nameVersion string) Option
- func WithURLs(addresses ...string) Option
- type Perm
- type Policy
- type ReqLimiter
- type StaticWebServer
- func (ws *StaticWebServer) ServeAssets() func(w http.ResponseWriter, r *http.Request)
- func (ws *StaticWebServer) ServeDir(contentType string) func(w http.ResponseWriter, r *http.Request)
- func (ws *StaticWebServer) ServeFile(urlPath, contentType string) func(w http.ResponseWriter, r *http.Request)
- func (ws *StaticWebServer) ServeImages() func(w http.ResponseWriter, r *http.Request)
- type TokenChecker
- type WebForm
Constants ¶
const ( HTTP = "http" HTTPS = "https" )
const FingerprintExplanation = `` /* 676-byte string literal not displayed */
FingerprintExplanation provides a description of the logged HTTP headers.
Variables ¶
var ( ErrNoTokenFound = errors.New("no JWT found") ErrInvalidCookie = errors.New("invalid cookie") ErrExpiredToken = errors.New("expired or invalid refresh token") )
var DefaultContactSettings = map[string][2]int{
"name": {60, 1},
"email": {60, 1},
"text": {900, 20},
"org-type": {20, 1},
"tel": {30, 1},
"want-call": {10, 1},
}
DefaultContactSettings is compliant with standard names for web form input fields: https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#inappropriate-for-the-control
var DefaultFileSettings = map[string][2]int{
"file": {1_000_000, 1},
}
DefaultFileSettings.
var DevOrigins = []*url.URL{
{Scheme: "http", Host: "localhost:"},
{Scheme: "http", Host: "192.168.1."},
}
DevOrigins provides the development origins: - yarn run vite --port 3000 - yarn run vite preview --port 5000 - localhost:8085 on multi devices: web auto-reload using https://github.com/synw/fwr - flutter run --web-port=8080 - 192.168.1.x + any port on tablet: mobile app using fast builtin auto-reload.
var ErrEmptyOPAFilename = errors.New("OPA: missing filename")
var ErrNonPrintable = errors.New("non-printable")
Functions ¶
func AppendPrefixes ¶ added in v0.5.1
func CORSHandler ¶ added in v0.17.0
CORSHandler uses restrictive CORS values.
func ConvertSize ¶ added in v0.17.0
ConvertSize converts a size in bytes into the most appropriate unit among KiB, MiB, GiB, TiB, PiB and EiB. 1 KiB is 1024 bytes as defined by the ISO/IEC 80000-13:2008 standard. See: https://wikiless.org/wiki/ISO%2FIEC_80000#Units_of_the_ISO_and_IEC_80000_series
func ConvertSize64 ¶ added in v0.17.0
ConvertSize64 is similar ConvertSize but takes in input an int64.
func FingerprintMD ¶ added in v0.17.0
FingerprintMD provide the browser fingerprint in markdown format. Attention: read the .
func InsertSchema ¶ added in v0.17.0
func InsertSchema(origins []string)
func InvalidPath ¶ added in v0.17.0
func InvalidPath(w http.ResponseWriter, r *http.Request)
func LoadPolicy ¶ added in v0.17.0
LoadPolicy checks the Rego filenames and loads them to build the OPA compiler.
func LogRequest ¶ added in v0.17.0
LogRequest is the middleware to log incoming HTTP request.
func LogRequestFingerprint ¶ added in v0.17.0
LogRequestFingerprint is the middleware to log incoming HTTP request and browser fingerprint.
func NewHash ¶ added in v0.17.0
NewHash uses HighwayHash is a hashing algorithm enabling high speed (especially on AMD64).
func NotImplemented ¶ added in v0.17.0
func NotImplemented(w http.ResponseWriter, r *http.Request)
func Obfuscate ¶ added in v0.17.0
Obfuscate hashes the input string to prevent logging sensitive information.
func OriginsFromURLs ¶ added in v0.9.0
func PrintVersion ¶ added in v0.17.0
func PrintVersion(v string)
PrintVersion computes and prints the version and (Git) commit information.
func Printable ¶ added in v0.17.0
Printable returns the position (index) of a Carriage Return "\r", or a Line Feed "\n", or any other ASCII control code (except space), or, as well as, bn invalid UTF-8 code. Printable returns -1 if the string is safely printable preventing log injection.
func PrintableRune ¶ added in v0.17.0
PrintableRune returns false if rune is a Carriage Return "\r", or a Line Feed "\n", or another ASCII control code (except space), or an invalid UTF-8 code. PrintableRune can be used to prevent log injection.
func Printables ¶ added in v0.17.0
Printables returns -1 when all the strings are printable else returns the position of the rejected character.
func ProbeCPU ¶ added in v0.17.0
func ProbeCPU() interface{ Stop() }
ProbeCPU is used like the following:
defer pprof.ProbeCPU.Stop()
When the caller reaches its function end, the defer executes Stop() that writes the file "cpu.pprof". To visualize "cpu.pprof" use the pprof tool:
cd ~/go go get -u github.com/google/pprof cd - pprof -http=: cpu.pprof
or using one single command line:
go run github.com/google/pprof@latest -http=: cpu.pprof
func RejectInvalidURI ¶ added in v0.17.0
RejectInvalidURI rejects HTTP requests having a Carriage Return "\r" or a Line Feed "\n" within the URI to prevent log injection.
func SafeHeader ¶ added in v0.17.0
SafeHeader return a stringifies a safe list of HTTP headers.
func Sanitize ¶ added in v0.17.0
Sanitize replaces control codes by the tofu symbol and invalid UTF-8 codes by the replacement character. Sanitize can be used to prevent log injection. Inspired from: https://wikiless.org/wiki/Replacement_character#Replacement_character https://graphicdesign.stackexchange.com/q/108297
func ServerHeader ¶
ServerHeader sets the Server HTTP header in the response.
func SetVersionFlag ¶ added in v0.17.0
SetVersionFlag register PrintVersion() for the version flag.
Example with default values:
import "github.com/teal-finance/garcon" func main() { garcon.SetVersionFlag(nil, "", "") flag.Parse() }
Example with custom values values:
import "github.com/teal-finance/garcon" func main() { v := garcon.Version("MyApp") garcon.SetVersionFlag(nil, "v", v) flag.Parse() }
func SplitClean ¶
SplitClean splits the values and trim them.
func StartPProfServer ¶ added in v0.17.0
func StartPProfServer(port int)
StartPProfServer starts a PProf server in background. Endpoints usage example:
curl http://localhost:6063/debug/pprof/allocs > allocs.pprof pprof -http=: allocs.pprof wget http://localhost:31415/debug/pprof/goroutine pprof -http=: goroutine wget http://localhost:31415/debug/pprof/heap pprof -http=: heap wget http://localhost:31415/debug/pprof/trace pprof -http=: trace
func TraversalPath ¶ added in v0.17.0
func TraversalPath(w http.ResponseWriter, r *http.Request) bool
TraversalPath returns true when path contains ".." to prevent path traversal attack.
func Value ¶ added in v0.12.3
Value returns the /endpoint/{key} (URL path) else the "key" form (HTTP body) else the "key" query string (URL) else the HTTP header.
func Version ¶ added in v0.17.0
Version format is "Program-1.2.3". If the program argument is empty, the format is "v1.2.3". The "vvv=v1.2.3" argument can be set during build-time with `-ldflags"-X 'myapp/pkg/info.V=v1.2.3'"`. If vvv is empty, Version uses the main module version.
func WriteJSONErr ¶ added in v0.17.0
Types ¶
type Chain ¶ added in v0.17.0
type Chain []Middleware
Chain acts as a list of http.Handler middleware. Chain is effectively immutable: once created, it will always hold the same set of middleware in the same order.
func NewChain ¶ added in v0.17.0
func NewChain(chain ...Middleware) Chain
NewChain creates a new chain, memorizing the given list of middleware. NewChain serves no other function, middleware is only constructed upon a call to Then().
func StartMetricsServer ¶ added in v0.17.0
StartMetricsServer creates and starts the Prometheus export server.
func (Chain) Append ¶ added in v0.17.0
func (c Chain) Append(chain ...Middleware) Chain
Append extends a chain, adding the specified middleware as the last ones in the request flow.
chain := chain.New(m1, m2) chain = chain.Append(m3, m4) // requests in chain go m1 -> m2 -> m3 -> m4
func (Chain) Then ¶ added in v0.17.0
Then chains the middleware and returns the final http.Handler.
chain.New(m1, m2, m3).Then(h)
is equivalent to:
m1(m2(m3(h)))
When the request comes in, it will be passed to m1, then m2, then m3 and finally, the given handler (assuming every middleware calls the following one).
A chain can be safely reused by calling Then() several times.
chain := chain.New(rateLimitHandler, csrfHandler) indexPipe = chain.Then(indexHandler) authPipe = chain.Then(authHandler)
Note: every call to Then() calls all middleware pieces. Thus several instances of the same middleware will be created when a chain is reused in this previous example. For proper middleware, this should cause no problem.
Then() treats nil as http.DefaultServeMux.
func (Chain) ThenFunc ¶ added in v0.17.0
func (c Chain) ThenFunc(fn http.HandlerFunc) http.Handler
ThenFunc works identically to Then, but takes a HandlerFunc instead of a Handler.
The following two statements are equivalent:
c.Then(http.HandlerFunc(fn)) c.ThenFunc(fn)
ThenFunc provides all the guarantees of Then.
type Checker ¶ added in v0.17.0
type Checker struct {
// contains filtered or unexported fields
}
func NewChecker ¶ added in v0.17.0
func (*Checker) Chk ¶ added in v0.17.0
Chk accepts the HTTP request only if it contains a valid cookie.
type ErrWriter ¶ added in v0.17.0
type ErrWriter string
ErrWriter enables writing useful JSON error message in the HTTP response body.
func NewErrWriter ¶ added in v0.17.0
NewErrWriter creates a ErrWriter structure.
func (ErrWriter) InvalidPath ¶ added in v0.17.0
func (errWriter ErrWriter) InvalidPath(w http.ResponseWriter, r *http.Request)
func (ErrWriter) NotImplemented ¶ added in v0.17.0
func (errWriter ErrWriter) NotImplemented(w http.ResponseWriter, r *http.Request)
func (ErrWriter) Write ¶ added in v0.17.0
func (errWriter ErrWriter) Write(w http.ResponseWriter, r *http.Request, statusCode int, messages ...any)
Write is a fast pretty-JSON marshaler dedicated to the HTTP error response. Write extends the JSON content when more than two messages are provided.
func (ErrWriter) WriteSafeJSONErr ¶ added in v0.17.0
func (errWriter ErrWriter) WriteSafeJSONErr(w http.ResponseWriter, r *http.Request, statusCode int, messages ...any)
WriteSafeJSONErr is a safe alternative to Write, may be slower despite the easyjson generated code. WriteSafeJSONErr concatenates all messages in "error" field.
type Garcon ¶
type Garcon struct { ConnState func(net.Conn, http.ConnState) Checker TokenChecker ErrWriter ErrWriter AllowedOrigins []string Middlewares Chain }
func (*Garcon) NewJWTChecker ¶ added in v0.6.0
func (*Garcon) NewSessionToken ¶ added in v0.13.1
func (g *Garcon) NewSessionToken(urls []*url.URL, secretKey []byte, expiry time.Duration, setIP bool) *incorruptible.Incorruptible
type Middleware ¶ added in v0.17.0
Middleware is a constructor function returning a http.Handler.
type Option ¶ added in v0.6.0
type Option func(*parameters)
func WithDocURL ¶ added in v0.6.0
func WithIncorruptible ¶ added in v0.13.4
WithIncorruptible enables the "session" cookies based on fast and tiny token. WithIncorruptible requires WithURLs() to set the Cookie name, secure, domain and path. WithIncorruptible is not compatible with WithJWT: use only one of them.
func WithJWT ¶ added in v0.6.0
WithJWT requires WithURLs() to set the Cookie name, secure, domain and path. WithJWT is not compatible with WithTkn: use only one of them.
func WithLimiter ¶ added in v0.6.0
func WithReqLogs ¶ added in v0.6.1
func WithServerHeader ¶ added in v0.6.0
type Policy ¶ added in v0.17.0
type Policy struct {
// contains filtered or unexported fields
}
Policy manages the Open Policy Agent (OPA). see https://www.openpolicyagent.org/docs/edge/integration/#integrating-with-the-go-api
type ReqLimiter ¶ added in v0.17.0
type ReqLimiter struct {
// contains filtered or unexported fields
}
func NewReqLimiter ¶ added in v0.17.0
func NewReqLimiter(maxReqBurst, maxReqPerMinute int, devMode bool, errWriter ErrWriter) ReqLimiter
type StaticWebServer ¶ added in v0.16.0
StaticWebServer is a webserver serving static files among HTML, CSS, JS and popular image formats.
func NewStaticWebServer ¶ added in v0.16.0
func NewStaticWebServer(dir string, errWriter ErrWriter) StaticWebServer
func (*StaticWebServer) ServeAssets ¶ added in v0.16.0
func (ws *StaticWebServer) ServeAssets() func(w http.ResponseWriter, r *http.Request)
ServeAssets detects the Content-Type depending on the asset extension.
func (*StaticWebServer) ServeDir ¶ added in v0.16.0
func (ws *StaticWebServer) ServeDir(contentType string) func(w http.ResponseWriter, r *http.Request)
ServeDir handles the static files using the same Content-Type.
func (*StaticWebServer) ServeFile ¶ added in v0.16.0
func (ws *StaticWebServer) ServeFile(urlPath, contentType string) func(w http.ResponseWriter, r *http.Request)
ServeFile handles one specific file (and its specific Content-Type).
func (*StaticWebServer) ServeImages ¶ added in v0.16.0
func (ws *StaticWebServer) ServeImages() func(w http.ResponseWriter, r *http.Request)
ServeImages detects the Content-Type depending on the image extension.
type TokenChecker ¶ added in v0.13.0
type TokenChecker interface { // Cookie returns the internal cookie (for test purpose). Cookie(i int) *http.Cookie // Set sets a cookie in the response when the request has no valid token. // Set searches the token in a cookie and in the first "Authorization" header. // Finally, Set stores the token attributes in the request context. Set(next http.Handler) http.Handler // Chk accepts requests only if it has a valid cookie. // Chk does not verify the "Authorization" header. // See the Vet() function to also verify the "Authorization" header. // Chk also stores the token attributes in the request context. // In dev. testing, Chk accepts any request but does not store invalid tokens. Chk(next http.Handler) http.Handler // Vet accepts requests having a valid token either in // the cookie or in the first "Authorization" header. // Vet also stores the decoded token in the request context. // In dev. testing, Vet accepts any request but does not store invalid tokens. Vet(next http.Handler) http.Handler }
type WebForm ¶ added in v0.16.0
type WebForm struct { ErrWriter ErrWriter Notifier notifier.Notifier Redirect string // TextLimits are used as security limits // to avoid being flooded by large web forms // and unexpected field names. // The map key is the input field name. // The map value is a pair of integers: // the max length and the max line breaks. // Use 0 to disable any limit. TextLimits map[string][2]int // FileLimits is similar to TextLimits // but for uploaded files. // The map value is a pair of integers: // the max size in runes of one file // and the max occurrences having same field name. // Use 0 to disable any limit. FileLimits map[string][2]int // MaxTotalLength includes the // form fields and browser fingerprints. MaxTotalLength int // contains filtered or unexported fields }
func NewContactForm ¶ added in v0.16.0
func (*WebForm) NotifyWebForm ¶ added in v0.17.0
func (form *WebForm) NotifyWebForm() func(w http.ResponseWriter, r *http.Request)
NotifyWebForm registers a web-form middleware that structures the filled form into markdown format and sends it to the Notifier.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
examples
|
|
Package timex extends the standard package time.
|
Package timex extends the standard package time. |