Ver código fonte

Add HTTPServer validation

Stan 21 horas atrás
pai
commit
6685a1aaab
2 arquivos alterados com 104 adições e 3 exclusões
  1. 29 3
      http_server.go
  2. 75 0
      http_server_validate.go

+ 29 - 3
http_server.go

@@ -58,9 +58,10 @@ func ResponseErr(status int, err error) *HTTPServerResponse {
 type HTTPServerCallback func(request *HTTPServerRequest) *HTTPServerResponse
 
 type HTTPServerHandler struct {
-	Callback HTTPServerCallback
-	Data     any
-	Buffer   int
+	Callback   HTTPServerCallback
+	Data       any
+	Buffer     int
+	Validators map[string][]Validator
 }
 
 type HTTPServerAction struct {
@@ -180,6 +181,31 @@ func (this *HTTPServer) ServeHTTP(responseStream http.ResponseWriter, requestStr
 			responseStream.WriteHeader(http.StatusInternalServerError)
 			return
 		}
+
+		// TODO: improve
+		if handler.Validators != nil {
+			value := reflect.ValueOf(handler.Data)
+			for field := range value.Fields() {
+				validators, ok := handler.Validators[field.Name]
+				if !ok {
+					continue
+				}
+
+				if len(validators) == 0 {
+					continue
+				}
+
+				for _, validator := range validators {
+					if validator.Validate(value.Interface()) {
+						continue
+					}
+
+					this.log.Error("malformed validation failed", LogValue("path", requestStream.URL.Path), LogError(err))
+					responseStream.WriteHeader(http.StatusNotAcceptable)
+					return
+				}
+			}
+		}
 	}
 
 	// Log query

+ 75 - 0
http_server_validate.go

@@ -0,0 +1,75 @@
+package fairwind
+
+import (
+	"regexp"
+)
+
+type Validator interface {
+	Validate(value any) bool
+}
+
+type MinLenghtValidator struct {
+	length int
+}
+
+func NewMinLenghtValidator(length int) *MinLenghtValidator {
+	return &MinLenghtValidator{
+		length: length,
+	}
+}
+
+func (this *MinLenghtValidator) Validate(value any) bool {
+	v, ok := value.(string)
+	if !ok {
+		return false
+	}
+
+	return len(v) >= this.length
+}
+
+type MaxLenghtValidator struct {
+	length int
+}
+
+func NewMaxLenghtValidator(length int) *MaxLenghtValidator {
+	return &MaxLenghtValidator{
+		length: length,
+	}
+}
+
+func (this *MaxLenghtValidator) Validate(value any) bool {
+	v, ok := value.(string)
+	if !ok {
+		return false
+	}
+
+	return len(v) <= this.length
+}
+
+type RegexValidator struct {
+	expression *regexp.Regexp
+}
+
+func NewRegexValidator(regex string) *RegexValidator {
+	expression, err := regexp.Compile(regex)
+	if err != nil {
+		return &RegexValidator{}
+	}
+
+	return &RegexValidator{
+		expression: expression,
+	}
+}
+
+func (this *RegexValidator) Validate(value any) bool {
+	if this.expression == nil {
+		return false
+	}
+
+	v, ok := value.(string)
+	if !ok {
+		return false
+	}
+
+	return this.expression.Match([]byte(v))
+}