Documentation
¶
Overview ¶
Package gg is the Garcon toolbox.
Index ¶
- Constants
- func AppendPrefixes(origins []string, prefixes ...string) []string
- func AppendURLs(urls []*url.URL, prefixes ...*url.URL) []*url.URL
- func B2S(b []byte) string
- func ConvertSize(sizeInBytes int) string
- func ConvertSize64(sizeInBytes int64) string
- func DecodeHexOrB64(in string, outLen int) ([]byte, error)
- func DecodeHexOrB64Bytes(in []byte, outLen int, reuse bool) ([]byte, error)
- func DecodeJSONRequest(w http.ResponseWriter, r *http.Request, msg any, maxBytes ...int) error
- func DecodeJSONResponse(r *http.Response, msg any, maxBytes ...int) error
- func Deduplicate[T comparable](duplicates []T) []T
- func EncodeHexOrB64(in string, isHex bool) string
- func EncodeHexOrB64Bytes(bin []byte, isHex bool) []byte
- func EnvInt(envvar string, fallback ...int) int
- func EnvStr(envvar string, fallback ...string) string
- func ExtractWords(csv string, dictionary []string) []string
- func FastSanitize(str string) string
- func FingerprintMD(r *http.Request) string
- func FingerprintTxt(r *http.Request) string
- func InvalidPath(w http.ResponseWriter, r *http.Request)
- func KeepSchemeHostOnly(urls []*url.URL) []string
- func Namify(str string) string
- func NotImplemented(w http.ResponseWriter, r *http.Request)
- func OverwriteBufferContent(b []byte)
- func ParseURLs(origins []string) []*url.URL
- func Printable(array ...string) int
- func PrintableRune(r rune) bool
- func ReadRequest(w http.ResponseWriter, r *http.Request, maxBytes ...int) ([]byte, error)
- func ReadResponse(r *http.Response, maxBytes ...int) ([]byte, error)
- func SafeHeader(r *http.Request, header string) string
- func Sanitize(slice ...string) string
- func SanitizeBytes(slice ...[]byte) []byte
- func Split(values string, separators ...rune) []string
- func SplitBytes(values []byte, separators ...rune) [][]byte
- func SplitClean(values string, separators ...rune) []string
- func SplitCleanBytes(values []byte, separators ...rune) [][]byte
- func SplitCleanedLines(str string) []string
- func UnmarshalJSONRequest[T json.Unmarshaler](w http.ResponseWriter, r *http.Request, msg T, maxBytes ...int) error
- func UnmarshalJSONResponse[T json.Unmarshaler](r *http.Response, msg T, maxBytes ...int) error
- func WriteErr(w http.ResponseWriter, r *http.Request, statusCode int, kv ...any)
- func WriteOK(w http.ResponseWriter, kv ...any)
- type Chain
- type LogNotifier
- type MattermostNotifier
- type Middleware
- type Notifier
- type RTChain
- type RTMiddleware
- type RoundTripperFunc
- type TelegramNotifier
- type Writer
- func (gw Writer) InvalidPath(w http.ResponseWriter, r *http.Request)
- func (gw Writer) NotImplemented(w http.ResponseWriter, r *http.Request)
- func (gw Writer) TraversalPath(w http.ResponseWriter, r *http.Request) bool
- func (gw Writer) WriteErr(w http.ResponseWriter, r *http.Request, statusCode int, kv ...any)
- func (gw Writer) WriteOK(w http.ResponseWriter, kv ...any)
Constants ¶
const ( SurrogateMin = 0xD800 SurrogateMax = 0xDFFF )
The code points in the surrogate range are not valid for UTF-8.
const FingerprintExplanation = `` /* 683-byte string literal not displayed */
FingerprintExplanation provides a description of the logged HTTP headers.
Variables ¶
This section is empty.
Functions ¶
func AppendPrefixes ¶
func ConvertSize ¶
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 ¶
ConvertSize64 is ConvertSize with int64 input. A good alternative is `ByteSize()“ from "github.com/gofiber/fiber".
func DecodeHexOrB64 ¶
DecodeHexOrB64 tries to decode the input string as hexadecimal or Base64 depending on the given output length. DecodeHexOrB64 supports the unpadded Base64 as defined in RFC 4648 §5 (URL encoding).
func DecodeHexOrB64Bytes ¶
DecodeHexOrB64Bytes tries to decode the input bytes as hexadecimal or Base64 depending on the given output length. DecodeHexOrB64Bytes supports the unpadded Base64 defined in RFC 4648 §5 for URL encoding. The "reuse" parameter allows to reuse the input bytes reducing the memory allocation. Caution: the input bytes are overwritten with reuse=true.
func DecodeJSONRequest ¶
DecodeJSONRequest decodes the JSON from the request body.
func DecodeJSONResponse ¶
DecodeJSONResponse decodes the JSON from the request body.
func Deduplicate ¶
func Deduplicate[T comparable](duplicates []T) []T
Deduplicate makes a slice of elements unique: it returns a slice with only the unique elements in it.
func EncodeHexOrB64 ¶
func EncodeHexOrB64Bytes ¶
func EnvInt ¶
EnvInt does the same as EnvStr but expects the value is an integer. EnvInt panics if the envvar value cannot be parsed as an integer.
func EnvStr ¶
EnvStr searches the environment variable (envvar) and returns its value if found, otherwise returns the optional fallback value. In absence of fallback, "" is returned.
func ExtractWords ¶
ExtractWords converts comma-separated values into a slice of unique words found in the dictionary.
The search is case-insensitive and is based on common prefix: the input value "foo" selects the first word in the dictionary that starts with "foo" (as "food" for example).
Moreover the special value "ALL" means all the dictionary words.
No guarantees are made about ordering. However the returned words are not duplicated. Note this operation alters the content of the dictionary: the found words are replaced by the last dictionary words. Clone the input dictionary if it needs to be preserved:
d2 := append([]string{}, dictionary...)
words := mm.ExtractWords(csv, d2)
func FastSanitize ¶
FastSanitize is an alternative of the Sanitize function using an optimized implementation.
func FingerprintMD ¶ added in v0.63.0
FingerprintMD provide the browser fingerprint in markdown format. Attention: read the .
func FingerprintTxt ¶ added in v0.63.0
FingerprintTxt logs like logIPMethodURL and also logs the browser fingerprint. Attention! FingerprintTxt provides personal data that may identify users. To comply with GDPR, the website data owner must have a legitimate reason to do so. Before enabling the fingerprinting, the user must understand it and give their freely-given informed consent such as the settings change from "no" to "yes".
func InvalidPath ¶
func InvalidPath(w http.ResponseWriter, r *http.Request)
func KeepSchemeHostOnly ¶
func Namify ¶
Namify extracts the wider "[a-zA-Z0-9_]+" string from the end of str. If str is a path or an URL, keep the last basename. Example: keep "myapp" from "https://example.com/path/myapp/" Namify also removes all punctuation characters except "_" and "-".
func NotImplemented ¶
func NotImplemented(w http.ResponseWriter, r *http.Request)
func OverwriteBufferContent ¶
func OverwriteBufferContent(b []byte)
OverwriteBufferContent is to erase a secret when it is no longer required.
func Printable ¶
Printable returns -1 when all the strings are safely printable else returns the position of the rejected character.
The non printable characters are:
- Carriage Return "\r"
- Line Feed "\n"
- other ASCII control codes (except space)
- invalid UTF-8 codes
Printable can be used to preventing log injection.
When multiple strings are passed, the returned position is sum with the string index multiplied by 1000.
func PrintableRune ¶
PrintableRune returns false if rune is a Carriage Return "\r", a Line Feed "\n", another ASCII control code (except space), or an invalid UTF-8 code. PrintableRune can be used to prevent log injection.
func ReadRequest ¶
func SafeHeader ¶
SafeHeader stringifies a safe list of HTTP header values.
func Sanitize ¶
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 SanitizeBytes ¶ added in v0.63.2
func SplitBytes ¶ added in v0.63.2
func SplitClean ¶
SplitClean splits the string into sanitized tokens.
func SplitCleanBytes ¶ added in v0.63.2
SplitCleanBytes splits the string into sanitized tokens.
func SplitCleanedLines ¶
SplitCleanedLines splits on linefeed, replaces the non-printable runes by spaces, trims leading/trailing/redundant spaces, and drops redundant blank lines.
func UnmarshalJSONRequest ¶
func UnmarshalJSONRequest[T json.Unmarshaler](w http.ResponseWriter, r *http.Request, msg T, maxBytes ...int) error
UnmarshalJSONRequest unmarshals the JSON from the request body.
func UnmarshalJSONResponse ¶
UnmarshalJSONResponse unmarshals the JSON from the request body.
func WriteOK ¶
func WriteOK(w http.ResponseWriter, kv ...any)
Types ¶
type Chain ¶
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 ¶
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 chain.Then().
func (Chain) Append ¶
func (c Chain) Append(chain ...Middleware) Chain
Append extends a chain, adding the provided middleware as the last ones in the request flow.
chain := gc.NewChain(m1, m2) chain = chain.Append(m3, m4) // requests in chain go m1 -> m2 -> m3 -> m4
func (Chain) Then ¶
Then chains the middlewares and returns the final http.Handler.
gc.Chain(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 := gc.Chain(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.
type LogNotifier ¶
type LogNotifier struct{}
LogNotifier implements a Notifier interface that logs the received notifications. LogNotifier can be used as a mocked Notifier or for debugging purpose or as a fallback when a real Notifier cannot be created for whatever reason.
func (LogNotifier) Notify ¶
func (n LogNotifier) Notify(msg string) error
Notify prints the messages to the logs.
type MattermostNotifier ¶
type MattermostNotifier struct {
// contains filtered or unexported fields
}
MattermostNotifier for sending messages to a Mattermost server.
func NewMattermostNotifier ¶
func NewMattermostNotifier(endpoint string) MattermostNotifier
NewMattermostNotifier creates a MattermostNotifier given a Mattermost server endpoint (see mattermost hooks).
func (MattermostNotifier) Notify ¶
func (n MattermostNotifier) Notify(msg string) error
Notify sends a message to a Mattermost server.
type Middleware ¶
Middleware is a constructor function returning a http.Handler.
type Notifier ¶
Notifier interface for sending messages.
func NewNotifier ¶
NewNotifier selects the Notifier type depending on the parameter pattern.
type RTChain ¶
type RTChain []RTMiddleware
RTChain acts as a list of http.RoundTripper middlewares. RTChain is effectively immutable: once created, it will always hold the same set of middleware in the same order.
func NewRTChain ¶
func NewRTChain(chain ...RTMiddleware) RTChain
NewRTChain creates a new chain of HTTP round trippers, memorizing the given list of RoundTrip middlewares. NewRTChain serves no other function, middlewares are only called upon a call to Then().
func (RTChain) Append ¶
func (c RTChain) Append(chain ...RTMiddleware) RTChain
Append extends a chain, adding the specified middlewares as the last ones in the request flow.
Append returns a new chain, leaving the original one untouched.
Example #1
stdChain := gc.NewRTChain(m1, m2) extChain := stdChain.Append(m3, m4) // requests in stdChain go m1 -> m2 // requests in extChain go m1 -> m2 -> m3 -> m4
Example #2
stdChain := gc.NewRTChain(m1, m2) ext1Chain := gc.NewRTChain(m3, m4) ext2Chain := stdChain.Append(ext1Chain...) // requests in stdChain go m1 -> m2 // requests in ext1Chain go m3 -> m4 // requests in ext2Chain go m1 -> m2 -> m3 -> m4
Example #3
aHtmlAfterNosurf := gc.NewRTChain(m2)
aHtml := gc.NewRTChain(m1, func(rt http.RoundTripper) http.RoundTripper {
csrf := nosurf.New(rt)
csrf.SetFailureHandler(aHtmlAfterNosurf.ThenFunc(csrfFail))
return csrf
}).Append(aHtmlAfterNosurf)
// requests to aHtml hitting nosurfs success handler go: m1 -> nosurf -> m2 -> rt
// requests to aHtml hitting nosurfs failure handler go: m1 -> nosurf -> m2 -> csrfFail
func (RTChain) Then ¶
func (c RTChain) Then(rt http.RoundTripper) http.RoundTripper
Then chains the middleware and returns the final http.RoundTripper.
gc.NewRTChain(m1, m2, m3).Then(rt)
is equivalent to:
m1(m2(m3(rt)))
When the request goes out, it will be passed to m1, then m2, then m3 and finally, the given round tripper (assuming every middleware calls the following one).
A chain can be safely reused by calling Then() several times.
stdStack := gc.NewRTChain(rateLimitHandler, csrfHandler) indexPipe = stdStack.Then(indexHandler) authPipe = stdStack.Then(authHandler)
Note that middlewares are called on every call to Then() and thus several instances of the same middleware will be created when a chain is reused in this way. For proper middleware, this should cause no problems.
Then() treats nil as http.DefaultTransport.
func (RTChain) ThenFunc ¶
func (c RTChain) ThenFunc(fn RoundTripperFunc) http.RoundTripper
ThenFunc works identically to Then, but takes a RoundTripperFunc instead of a RoundTripper.
The following two statements are equivalent:
c.Then(http.RoundTripperFunc(fn)) c.ThenFunc(fn)
ThenFunc provides all the guarantees of Then.
type RTMiddleware ¶
type RTMiddleware func(http.RoundTripper) http.RoundTripper
RTMiddleware for a piece of RoundTrip middleware. Some middleware uses this out of the box, so in most cases you can just use somepackage.New().
type RoundTripperFunc ¶
RoundTripperFunc is to RoundTripper what HandlerFunc is to Handler. It is a higher-order function that enables chaining of RoundTrippers with the middleware pattern.
type TelegramNotifier ¶
type TelegramNotifier struct {
// contains filtered or unexported fields
}
TelegramNotifier is a Notifier for a specific Telegram chat room.
func NewTelegramNotifier ¶
func NewTelegramNotifier(endpoint, chatID string) TelegramNotifier
NewTelegramNotifier creates a TelegramNotifier.
func (TelegramNotifier) Notify ¶
func (n TelegramNotifier) Notify(msg string) error
Notify sends a message to the Telegram server.
type Writer ¶
type Writer string
Writer enables writing useful JSON error message in the HTTP response body.
func (Writer) InvalidPath ¶
func (gw Writer) InvalidPath(w http.ResponseWriter, r *http.Request)
func (Writer) NotImplemented ¶
func (gw Writer) NotImplemented(w http.ResponseWriter, r *http.Request)
func (Writer) TraversalPath ¶
TraversalPath returns true when path contains ".." to prevent path traversal attack.