Add request source

Add "request" source with support for "method" and "remote-addr"
parameters.  Both values are taken from the raw http.Request object.

Fixes #312
This commit is contained in:
Cameron Moore 2020-11-20 16:32:55 -06:00
parent e513eb4bf4
commit 346c761ef6
6 changed files with 136 additions and 28 deletions

View file

@ -35,6 +35,7 @@ const (
SourceQuery string = "url"
SourceQueryAlias string = "query"
SourcePayload string = "payload"
SourceRequest string = "request"
SourceString string = "string"
SourceEntirePayload string = "entire-payload"
SourceEntireQuery string = "entire-query"
@ -438,12 +439,30 @@ func (ha *Argument) Get(r *Request) (string, error) {
case SourceHeader:
source = &r.Headers
key = textproto.CanonicalMIMEHeaderKey(ha.Name)
case SourceQuery, SourceQueryAlias:
source = &r.Query
case SourcePayload:
source = &r.Payload
case SourceString:
return ha.Name, nil
case SourceRequest:
if r == nil || r.RawRequest == nil {
return "", errors.New("request is nil")
}
switch ha.Name {
case "remote-addr":
return r.RawRequest.RemoteAddr, nil
case "method":
return r.RawRequest.Method, nil
default:
return "", fmt.Errorf("unsupported request key: %q", ha.Name)
}
case SourceEntirePayload:
res, err := json.Marshal(&r.Payload)
if err != nil {
@ -451,6 +470,7 @@ func (ha *Argument) Get(r *Request) (string, error) {
}
return string(res), nil
case SourceEntireHeaders:
res, err := json.Marshal(&r.Headers)
if err != nil {
@ -458,6 +478,7 @@ func (ha *Argument) Get(r *Request) (string, error) {
}
return string(res), nil
case SourceEntireQuery:
res, err := json.Marshal(&r.Query)
if err != nil {

View file

@ -255,27 +255,31 @@ func TestExtractParameter(t *testing.T) {
var argumentGetTests = []struct {
source, name string
headers, query, payload map[string]interface{}
request *http.Request
value string
ok bool
}{
{"header", "a", map[string]interface{}{"A": "z"}, nil, nil, "z", true},
{"url", "a", nil, map[string]interface{}{"a": "z"}, nil, "z", true},
{"payload", "a", nil, nil, map[string]interface{}{"a": "z"}, "z", true},
{"string", "a", nil, nil, map[string]interface{}{"a": "z"}, "a", true},
{"header", "a", map[string]interface{}{"A": "z"}, nil, nil, nil, "z", true},
{"url", "a", nil, map[string]interface{}{"a": "z"}, nil, nil, "z", true},
{"payload", "a", nil, nil, map[string]interface{}{"a": "z"}, nil, "z", true},
{"request", "method", nil, nil, map[string]interface{}{"a": "z"}, &http.Request{Method: "POST", RemoteAddr: "127.0.0.1:1234"}, "POST", true},
{"request", "remote-addr", nil, nil, map[string]interface{}{"a": "z"}, &http.Request{Method: "POST", RemoteAddr: "127.0.0.1:1234"}, "127.0.0.1:1234", true},
{"string", "a", nil, nil, map[string]interface{}{"a": "z"}, nil, "a", true},
// failures
{"header", "a", nil, map[string]interface{}{"a": "z"}, map[string]interface{}{"a": "z"}, "", false}, // nil headers
{"url", "a", map[string]interface{}{"A": "z"}, nil, map[string]interface{}{"a": "z"}, "", false}, // nil query
{"payload", "a", map[string]interface{}{"A": "z"}, map[string]interface{}{"a": "z"}, nil, "", false}, // nil payload
{"foo", "a", map[string]interface{}{"A": "z"}, nil, nil, "", false}, // invalid source
{"header", "a", nil, map[string]interface{}{"a": "z"}, map[string]interface{}{"a": "z"}, nil, "", false}, // nil headers
{"url", "a", map[string]interface{}{"A": "z"}, nil, map[string]interface{}{"a": "z"}, nil, "", false}, // nil query
{"payload", "a", map[string]interface{}{"A": "z"}, map[string]interface{}{"a": "z"}, nil, nil, "", false}, // nil payload
{"foo", "a", map[string]interface{}{"A": "z"}, nil, nil, nil, "", false}, // invalid source
}
func TestArgumentGet(t *testing.T) {
for _, tt := range argumentGetTests {
a := Argument{tt.source, tt.name, "", false}
r := &Request{
Headers: tt.headers,
Query: tt.query,
Payload: tt.payload,
Headers: tt.headers,
Query: tt.query,
Payload: tt.payload,
RawRequest: tt.request,
}
value, err := a.Get(r)
if (err == nil) != tt.ok || value != tt.value {