diff --git a/pkg/request/request.go b/pkg/request/request.go index cbf16b5c..dc979b4e 100644 --- a/pkg/request/request.go +++ b/pkg/request/request.go @@ -15,3 +15,21 @@ func GetUrl(header api.RequestHeaderMap) *url.URL { } return uri } + +// GetHeaders returns a plain map represents the headers. The returned headers won't +// contain any pseudo header like `:authority`. +func GetHeaders(header api.RequestHeaderMap) map[string][]string { + hdr := map[string][]string{} + header.Range(func(k, v string) bool { + if k[0] == ':' { + return true + } + if entry, ok := hdr[k]; !ok { + hdr[k] = []string{v} + } else { + hdr[k] = append(entry, v) + } + return true + }) + return hdr +} diff --git a/plugins/opa/README.md b/plugins/opa/README.md index 23a38109..74485776 100644 --- a/plugins/opa/README.md +++ b/plugins/opa/README.md @@ -31,7 +31,11 @@ Here is the JSON data Moe sends to the OPA: "b": [""] }, "method": "GET", - "host": "localhost" + "host": "localhost:10000", + "headers": { + "fruit": ["apple", "banana"], + "pet": ["dog"] + } } } } @@ -39,7 +43,9 @@ Here is the JSON data Moe sends to the OPA: Note that: -* `method` is always uppercase, while `host` and `scheme` are always lowecase. +* `method` is always uppercase, while `host`, `headers` and `scheme` are always lowecase. +* `host` will contain the port if the `:authority` header sent by the client has the port. +* Multiple `headers` and `query` in the same name will be passed in an array. The data can be read as `input` document in OPA. diff --git a/plugins/opa/filter.go b/plugins/opa/filter.go index 8ecf9cde..784981b9 100644 --- a/plugins/opa/filter.go +++ b/plugins/opa/filter.go @@ -33,11 +33,13 @@ var opaResponse struct { func (f *filter) buildInput(header api.RequestHeaderMap) map[string]interface{} { uri := request.GetUrl(header) + headers := request.GetHeaders(header) req := map[string]interface{}{ - "method": header.Method(), - "scheme": header.Scheme(), - "host": header.Host(), - "path": uri.Path, + "method": header.Method(), + "scheme": header.Scheme(), + "host": header.Host(), + "path": uri.Path, + "headers": headers, } if uri.RawQuery != "" { req["query"] = map[string][]string(uri.Query()) diff --git a/plugins/opa/filter_test.go b/plugins/opa/filter_test.go index 42bf671d..4cdf77d9 100644 --- a/plugins/opa/filter_test.go +++ b/plugins/opa/filter_test.go @@ -30,6 +30,8 @@ func TestOpaRemote(t *testing.T) { })(cb) hdr := envoy.NewRequestHeaderMap(http.Header(map[string][]string{ ":path": {"/?a=1&b&c=true&c=foo"}, + "pet": {"cat"}, + "fruit": {"apple", "banana"}, })) tests := []struct { @@ -53,6 +55,10 @@ func TestOpaRemote(t *testing.T) { "b": []interface{}{""}, "c": []interface{}{"true", "foo"}, }, + "headers": map[string]interface{}{ + "pet": []interface{}{"cat"}, + "fruit": []interface{}{"apple", "banana"}, + }, }, input["input"].(map[string]interface{})["request"]) }, },