Skip to content

Commit

Permalink
Move proxy origin scheme validation to config #59
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcel Ludwig committed Nov 24, 2020
1 parent 2452d0f commit 0b4dd6c
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 11 deletions.
41 changes: 35 additions & 6 deletions config/runtime/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io/ioutil"
"net"
"net/http"
url2 "net/url"
"os"
"path"
"regexp"
Expand Down Expand Up @@ -207,13 +208,19 @@ func NewServerConfiguration(conf *config.Gateway, httpConf *HTTPConfig, log *log
return nil, err
}

if inlineConf.Name == "" && !hasAttribute(conf.Context, "origin", inlineConf.Options) {
if inlineConf.Name == "" && getAttribute(conf.Context, "origin", inlineConf.Options) == "" {
return nil, fmt.Errorf("api inline backend requires an origin attribute: %q", pattern)
}
} else if err != nil { // TODO hcl.diagnostics error
return nil, fmt.Errorf("range: %s: %v", endpoint.InlineDefinition.MissingItemRange().String(), err)
}

if e := validateOrigin(
getAttribute(conf.Context, "origin", inlineConf.Options),
inlineConf.Options.MissingItemRange()); e != nil {
return nil, e
}

setACHandlerFn(inlineBackend)
err = setRoutesFromHosts(serverConfiguration, defaultPort, srvConf.Hosts, pattern, api[endpoint], KindAPI)
if err != nil {
Expand Down Expand Up @@ -255,8 +262,9 @@ func newBackendsFromDefinitions(conf *config.Gateway, log *logrus.Entry) (map[st
return nil, fmt.Errorf("backend name must be unique: %q", beConf.Name)
}

if !hasAttribute(conf.Context, "origin", beConf.Options) {
return nil, fmt.Errorf("backend %q: origin attribute is required", beConf.Name)
origin := getAttribute(conf.Context, "origin", beConf.Options)
if e := validateOrigin(origin, beConf.Options.MissingItemRange()); e != nil {
return nil, e
}

beConf, _ = defaultBackendConf.Merge(beConf)
Expand All @@ -270,16 +278,37 @@ func newBackendsFromDefinitions(conf *config.Gateway, log *logrus.Entry) (map[st
return backends, nil
}

func validateOrigin(origin string, ctxRange hcl.Range) error {
diagErr := &hcl.Diagnostic{
Subject: &ctxRange,
Summary: "invalid backend.origin value",
}
if origin == "" {
diagErr.Detail = "origin attribute is required"
return hcl.Diagnostics{diagErr}
}
url, err := url2.Parse(origin)
if err != nil {
diagErr.Detail = fmt.Sprintf("url parse error: %v", err)
return hcl.Diagnostics{diagErr}
}
if url.Scheme != "http" && url.Scheme != "https" {
diagErr.Detail = fmt.Sprintf("valid http scheme required for origin: %q", origin)
return hcl.Diagnostics{diagErr}
}
return nil
}

// hasAttribute checks for a configured string value and ignores unrelated errors.
func hasAttribute(ctx *hcl.EvalContext, name string, body hcl.Body) bool {
func getAttribute(ctx *hcl.EvalContext, name string, body hcl.Body) string {
attr, _ := body.JustAttributes()

if _, ok := attr[name]; !ok {
return false
return ""
}

val, _ := attr[name].Expr.Value(ctx)
return seetie.ValueToString(val) != ""
return seetie.ValueToString(val)
}

// validatePortHosts ensures expected host:port formats and unique hosts per port.
Expand Down
5 changes: 0 additions & 5 deletions handler/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,6 @@ func (c *CORSOptions) AllowsOrigin(origin string) bool {
}

func NewProxy(options *ProxyOptions, log *logrus.Entry, srvOpts *server.Options, evalCtx *hcl.EvalContext) (http.Handler, error) {
// TODO: validate at config level
//if originURL.Scheme != "http" && originURL.Scheme != "https" {
// return nil, SchemeRequiredError
//}

logConf := *logging.DefaultConfig
logConf.TypeFieldKey = "couper_backend"
env.DecodeWithPrefix(&logConf, "BACKEND_")
Expand Down

0 comments on commit 0b4dd6c

Please sign in to comment.