mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-16 21:56:40 -05:00
v2: fixes query matcher parsing (#2901)
* fixes query matcher parsing * return correct argument error when parsing query matcher
This commit is contained in:
parent
7c7ef8d40e
commit
8b7d6a9ee8
3 changed files with 137 additions and 5 deletions
66
caddyconfig/httpcaddyfile/parser_test.go
Normal file
66
caddyconfig/httpcaddyfile/parser_test.go
Normal file
|
@ -0,0 +1,66 @@
|
|||
// Copyright 2015 Matthew Holt and The Caddy Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package httpcaddyfile
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
caddyfile "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
|
||||
)
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
|
||||
for i, tc := range []struct {
|
||||
input string
|
||||
expectWarn bool
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
input: `http://localhost
|
||||
matcher debug {
|
||||
query showdebug=1
|
||||
}
|
||||
`,
|
||||
expectWarn: false,
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
input: `http://localhost
|
||||
matcher debug {
|
||||
query bad format
|
||||
}
|
||||
`,
|
||||
expectWarn: false,
|
||||
expectError: true,
|
||||
},
|
||||
} {
|
||||
|
||||
adapter := caddyfile.Adapter{
|
||||
ServerType: ServerType{},
|
||||
}
|
||||
|
||||
_, warnings, err := adapter.Adapt([]byte(tc.input), nil)
|
||||
|
||||
if len(warnings) > 0 != tc.expectWarn {
|
||||
t.Errorf("Test %d warning expectation failed Expected: %v, got %v", i, tc.expectWarn, warnings)
|
||||
continue
|
||||
}
|
||||
|
||||
if err != nil != tc.expectError {
|
||||
t.Errorf("Test %d error expectation failed Expected: %v, got %s", i, tc.expectError, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
|
@ -255,8 +255,16 @@ func (MatchQuery) CaddyModule() caddy.ModuleInfo {
|
|||
|
||||
// UnmarshalCaddyfile implements caddyfile.Unmarshaler.
|
||||
func (m *MatchQuery) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
|
||||
if *m == nil {
|
||||
*m = make(map[string][]string)
|
||||
}
|
||||
|
||||
for d.Next() {
|
||||
parts := strings.SplitN(d.Val(), "=", 2)
|
||||
var query string
|
||||
if !d.Args(&query) {
|
||||
return d.ArgErr()
|
||||
}
|
||||
parts := strings.SplitN(query, "=", 2)
|
||||
if len(parts) != 2 {
|
||||
return d.Errf("malformed query matcher token: %s; must be in param=val format", d.Val())
|
||||
}
|
||||
|
@ -268,10 +276,12 @@ func (m *MatchQuery) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
|
|||
// Match returns true if r matches m.
|
||||
func (m MatchQuery) Match(r *http.Request) bool {
|
||||
for param, vals := range m {
|
||||
paramVal := r.URL.Query().Get(param)
|
||||
for _, v := range vals {
|
||||
if paramVal == v {
|
||||
return true
|
||||
paramVal, found := r.URL.Query()[param]
|
||||
if found {
|
||||
for _, v := range vals {
|
||||
if paramVal[0] == v || v == "*" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -391,6 +391,62 @@ func TestHeaderMatcher(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestQueryMatcher(t *testing.T) {
|
||||
for i, tc := range []struct {
|
||||
scenario string
|
||||
match MatchQuery
|
||||
input string
|
||||
expect bool
|
||||
}{
|
||||
{
|
||||
scenario: "non match against a specific value",
|
||||
match: MatchQuery{"debug": []string{"1"}},
|
||||
input: "/",
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
scenario: "match against a specific value",
|
||||
match: MatchQuery{"debug": []string{"1"}},
|
||||
input: "/?debug=1",
|
||||
expect: true,
|
||||
},
|
||||
{
|
||||
scenario: "match against a wildcard",
|
||||
match: MatchQuery{"debug": []string{"*"}},
|
||||
input: "/?debug=something",
|
||||
expect: true,
|
||||
},
|
||||
{
|
||||
scenario: "non match against a wildcarded",
|
||||
match: MatchQuery{"debug": []string{"*"}},
|
||||
input: "/?other=something",
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
scenario: "match against an empty value",
|
||||
match: MatchQuery{"debug": []string{""}},
|
||||
input: "/?debug",
|
||||
expect: true,
|
||||
},
|
||||
{
|
||||
scenario: "non match against an empty value",
|
||||
match: MatchQuery{"debug": []string{""}},
|
||||
input: "/?someparam",
|
||||
expect: false,
|
||||
},
|
||||
} {
|
||||
|
||||
u, _ := url.Parse(tc.input)
|
||||
|
||||
req := &http.Request{URL: u}
|
||||
actual := tc.match.Match(req)
|
||||
if actual != tc.expect {
|
||||
t.Errorf("Test %d %v: Expected %t, got %t for '%s'", i, tc.match, tc.expect, actual, tc.input)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeaderREMatcher(t *testing.T) {
|
||||
for i, tc := range []struct {
|
||||
match MatchHeaderRE
|
||||
|
|
Loading…
Reference in a new issue