k3s/vendor/github.com/emicklei/go-restful/path_expression.go

75 lines
2.5 KiB
Go
Raw Normal View History

2019-01-12 04:58:27 +00:00
package restful
// Copyright 2013 Ernest Micklei. All rights reserved.
// Use of this source code is governed by a license
// that can be found in the LICENSE file.
import (
"bytes"
"fmt"
"regexp"
"strings"
)
// PathExpression holds a compiled path expression (RegExp) needed to match against
// Http request paths and to extract path parameter values.
type pathExpression struct {
2019-09-27 21:51:53 +00:00
LiteralCount int // the number of literal characters (means those not resulting from template variable substitution)
VarNames []string // the names of parameters (enclosed by {}) in the path
VarCount int // the number of named parameters (enclosed by {}) in the path
2019-01-12 04:58:27 +00:00
Matcher *regexp.Regexp
Source string // Path as defined by the RouteBuilder
tokens []string
}
// NewPathExpression creates a PathExpression from the input URL path.
// Returns an error if the path is invalid.
func newPathExpression(path string) (*pathExpression, error) {
2019-09-27 21:51:53 +00:00
expression, literalCount, varNames, varCount, tokens := templateToRegularExpression(path)
2019-01-12 04:58:27 +00:00
compiled, err := regexp.Compile(expression)
if err != nil {
return nil, err
}
2019-09-27 21:51:53 +00:00
return &pathExpression{literalCount, varNames, varCount, compiled, expression, tokens}, nil
2019-01-12 04:58:27 +00:00
}
// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-370003.7.3
2019-09-27 21:51:53 +00:00
func templateToRegularExpression(template string) (expression string, literalCount int, varNames []string, varCount int, tokens []string) {
2019-01-12 04:58:27 +00:00
var buffer bytes.Buffer
buffer.WriteString("^")
//tokens = strings.Split(template, "/")
tokens = tokenizePath(template)
for _, each := range tokens {
if each == "" {
continue
}
buffer.WriteString("/")
if strings.HasPrefix(each, "{") {
// check for regular expression in variable
colon := strings.Index(each, ":")
2019-09-27 21:51:53 +00:00
var varName string
2019-01-12 04:58:27 +00:00
if colon != -1 {
// extract expression
2019-09-27 21:51:53 +00:00
varName = strings.TrimSpace(each[1:colon])
2019-01-12 04:58:27 +00:00
paramExpr := strings.TrimSpace(each[colon+1 : len(each)-1])
if paramExpr == "*" { // special case
buffer.WriteString("(.*)")
} else {
buffer.WriteString(fmt.Sprintf("(%s)", paramExpr)) // between colon and closing moustache
}
} else {
// plain var
2019-09-27 21:51:53 +00:00
varName = strings.TrimSpace(each[1 : len(each)-1])
2019-01-12 04:58:27 +00:00
buffer.WriteString("([^/]+?)")
}
2019-09-27 21:51:53 +00:00
varNames = append(varNames, varName)
2019-01-12 04:58:27 +00:00
varCount += 1
} else {
literalCount += len(each)
encoded := each // TODO URI encode
buffer.WriteString(regexp.QuoteMeta(encoded))
}
}
2019-09-27 21:51:53 +00:00
return strings.TrimRight(buffer.String(), "/") + "(/.*)?$", literalCount, varNames, varCount, tokens
2019-01-12 04:58:27 +00:00
}