80 lines
1.9 KiB
Go
80 lines
1.9 KiB
Go
|
package config
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"net/http"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
// Parse builds a server configuration from a json reader and checks for most format errors.
|
||
|
func Parse(r io.Reader) (Services, error) {
|
||
|
services := make(Services, 0)
|
||
|
|
||
|
err := json.NewDecoder(r).Decode(&services)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("%s: %w", ErrRead, err)
|
||
|
}
|
||
|
|
||
|
err = services.checkAndFormat()
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("%s: %w", ErrFormat, err)
|
||
|
}
|
||
|
|
||
|
if services.collide() {
|
||
|
return nil, fmt.Errorf("%s: %w", ErrFormat, ErrPatternCollision)
|
||
|
}
|
||
|
|
||
|
return services, nil
|
||
|
}
|
||
|
|
||
|
// collide returns if there is collision between services
|
||
|
func (svc Services) collide() bool {
|
||
|
// todo: implement pattern collision using types to check if braces can be equal to fixed uri parts
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
// Find a service matching an incoming HTTP request
|
||
|
func (svc Services) Find(r *http.Request) *Service {
|
||
|
for _, service := range svc {
|
||
|
if service.Match(r) {
|
||
|
return service
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// checkAndFormat checks for errors and missing fields and sets default values for optional fields.
|
||
|
func (svc Services) checkAndFormat() error {
|
||
|
for _, service := range svc {
|
||
|
|
||
|
// check method
|
||
|
err := service.checkMethod()
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("%s '%s' [method]: %w", service.Method, service.Pattern, err)
|
||
|
}
|
||
|
|
||
|
// check pattern
|
||
|
service.Pattern = strings.Trim(service.Pattern, " \t\r\n")
|
||
|
err = service.checkPattern()
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("%s '%s' [path]: %w", service.Method, service.Pattern, err)
|
||
|
}
|
||
|
|
||
|
// check description
|
||
|
if len(strings.Trim(service.Description, " \t\r\n")) < 1 {
|
||
|
return fmt.Errorf("%s '%s' [description]: %w", service.Method, service.Pattern, ErrMissingDescription)
|
||
|
}
|
||
|
|
||
|
// check input parameters
|
||
|
err = service.checkAndFormatInput()
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("%s '%s' [in]: %w", service.Method, service.Pattern, err)
|
||
|
}
|
||
|
|
||
|
}
|
||
|
return nil
|
||
|
}
|