Issue #16: Added regex support for matching headers

Issue #16 : Addressed code review and refactored support for regex into
a separate function

Added compiled regex to route matcher
This commit is contained in:
Craig Jellick
2015-05-29 14:16:30 -07:00
committed by Clint Ryan
parent 94903de8c9
commit c0a5cbce5a
4 changed files with 118 additions and 11 deletions

60
mux.go
View File

@@ -8,6 +8,7 @@ import (
"fmt"
"net/http"
"path"
"regexp"
"github.com/gorilla/context"
)
@@ -313,13 +314,21 @@ func uniqueVars(s1, s2 []string) error {
return nil
}
// mapFromPairs converts variadic string parameters to a string map.
func mapFromPairs(pairs ...string) (map[string]string, error) {
func checkPairs(pairs ...string) (int, error) {
length := len(pairs)
if length%2 != 0 {
return nil, fmt.Errorf(
return length, fmt.Errorf(
"mux: number of parameters must be multiple of 2, got %v", pairs)
}
return length, nil
}
// mapFromPairs converts variadic string parameters to a string map.
func mapFromPairsToString(pairs ...string) (map[string]string, error) {
length, err := checkPairs(pairs...)
if err != nil {
return nil, err
}
m := make(map[string]string, length/2)
for i := 0; i < length; i += 2 {
m[pairs[i]] = pairs[i+1]
@@ -327,6 +336,19 @@ func mapFromPairs(pairs ...string) (map[string]string, error) {
return m, nil
}
func mapFromPairsToRegex(pairs ...string) (map[string]*regexp.Regexp, error) {
length, err := checkPairs(pairs...)
if err != nil {
return nil, err
}
m := make(map[string]*regexp.Regexp, length/2)
for i := 0; i < length; i += 2 {
regex, _ := regexp.Compile(pairs[i+1])
m[pairs[i]] = regex
}
return m, nil
}
// matchInArray returns true if the given string value is in the array.
func matchInArray(arr []string, value string) bool {
for _, v := range arr {
@@ -337,9 +359,10 @@ func matchInArray(arr []string, value string) bool {
return false
}
type equals func(interface{}, interface{}) bool
// matchMap returns true if the given key/value pairs exist in a given map.
func matchMap(toCheck map[string]string, toMatch map[string][]string,
canonicalKey bool) bool {
func matchMapWithString(toCheck map[string]string, toMatch map[string][]string, canonicalKey bool) bool {
for k, v := range toCheck {
// Check if key exists.
if canonicalKey {
@@ -364,3 +387,30 @@ func matchMap(toCheck map[string]string, toMatch map[string][]string,
}
return true
}
// matchMap returns true if the given key/value pairs exist in a given map.
func matchMapWithRegex(toCheck map[string]*regexp.Regexp, toMatch map[string][]string, canonicalKey bool) bool {
for k, v := range toCheck {
// Check if key exists.
if canonicalKey {
k = http.CanonicalHeaderKey(k)
}
if values := toMatch[k]; values == nil {
return false
} else if v != nil {
// If value was defined as an empty string we only check that the
// key exists. Otherwise we also check for equality.
valueExists := false
for _, value := range values {
if v.MatchString(value) {
valueExists = true
break
}
}
if !valueExists {
return false
}
}
}
return true
}