mirror of
https://github.com/go-acme/lego
synced 2026-03-14 14:35:48 +01:00
97 lines
1.9 KiB
Go
97 lines
1.9 KiB
Go
package servermock
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"regexp"
|
|
"slices"
|
|
)
|
|
|
|
// FormLink is a type used for validating and processing form data in HTTP requests.
|
|
// It supports strict validation, predefined values, and regex-based checks to ensure form compliance.
|
|
type FormLink struct {
|
|
values url.Values
|
|
regexes map[string]*regexp.Regexp
|
|
strict bool
|
|
usePostForm bool
|
|
statusCode int
|
|
}
|
|
|
|
func CheckForm() *FormLink {
|
|
return &FormLink{
|
|
values: url.Values{},
|
|
regexes: map[string]*regexp.Regexp{},
|
|
statusCode: http.StatusBadRequest,
|
|
}
|
|
}
|
|
|
|
func (l *FormLink) Bind(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
|
err := req.ParseForm()
|
|
if err != nil {
|
|
http.Error(rw, err.Error(), l.statusCode)
|
|
return
|
|
}
|
|
|
|
form := req.Form
|
|
if l.usePostForm {
|
|
form = req.PostForm
|
|
}
|
|
|
|
if l.strict {
|
|
if len(form) != len(l.values)+len(l.regexes) {
|
|
msg := fmt.Sprintf("invalid query parameters, got %v, want %v", req.Form, l.values)
|
|
http.Error(rw, msg, l.statusCode)
|
|
|
|
return
|
|
}
|
|
}
|
|
|
|
for k, v := range l.values {
|
|
value := form[k]
|
|
if !slices.Equal(v, value) {
|
|
msg := fmt.Sprintf("invalid %q form value, got %q, want %q", k, value, v)
|
|
http.Error(rw, msg, l.statusCode)
|
|
|
|
return
|
|
}
|
|
}
|
|
|
|
for k, exp := range l.regexes {
|
|
value := form.Get(k)
|
|
if !exp.MatchString(value) {
|
|
msg := fmt.Sprintf("invalid %q form value, %q doesn't match to %q", k, value, exp)
|
|
http.Error(rw, msg, l.statusCode)
|
|
|
|
return
|
|
}
|
|
}
|
|
|
|
next.ServeHTTP(rw, req)
|
|
})
|
|
}
|
|
|
|
func (l *FormLink) Strict() *FormLink {
|
|
l.strict = true
|
|
|
|
return l
|
|
}
|
|
|
|
func (l *FormLink) UsePostForm() *FormLink {
|
|
l.usePostForm = true
|
|
|
|
return l
|
|
}
|
|
|
|
func (l *FormLink) With(name, value string) *FormLink {
|
|
l.values.Set(name, value)
|
|
|
|
return l
|
|
}
|
|
|
|
func (l *FormLink) WithRegexp(name, exp string) *FormLink {
|
|
l.regexes[name] = regexp.MustCompile(exp)
|
|
|
|
return l
|
|
}
|