...

Source file src/github.com/emicklei/go-restful/v3/path_expression.go

Documentation: github.com/emicklei/go-restful/v3

     1  package restful
     2  
     3  // Copyright 2013 Ernest Micklei. All rights reserved.
     4  // Use of this source code is governed by a license
     5  // that can be found in the LICENSE file.
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"regexp"
    11  	"strings"
    12  )
    13  
    14  // PathExpression holds a compiled path expression (RegExp) needed to match against
    15  // Http request paths and to extract path parameter values.
    16  type pathExpression struct {
    17  	LiteralCount int      // the number of literal characters (means those not resulting from template variable substitution)
    18  	VarNames     []string // the names of parameters (enclosed by {}) in the path
    19  	VarCount     int      // the number of named parameters (enclosed by {}) in the path
    20  	Matcher      *regexp.Regexp
    21  	Source       string // Path as defined by the RouteBuilder
    22  	tokens       []string
    23  }
    24  
    25  // NewPathExpression creates a PathExpression from the input URL path.
    26  // Returns an error if the path is invalid.
    27  func newPathExpression(path string) (*pathExpression, error) {
    28  	expression, literalCount, varNames, varCount, tokens := templateToRegularExpression(path)
    29  	compiled, err := regexp.Compile(expression)
    30  	if err != nil {
    31  		return nil, err
    32  	}
    33  	return &pathExpression{literalCount, varNames, varCount, compiled, expression, tokens}, nil
    34  }
    35  
    36  // http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-370003.7.3
    37  func templateToRegularExpression(template string) (expression string, literalCount int, varNames []string, varCount int, tokens []string) {
    38  	var buffer bytes.Buffer
    39  	buffer.WriteString("^")
    40  	//tokens = strings.Split(template, "/")
    41  	tokens = tokenizePath(template)
    42  	for _, each := range tokens {
    43  		if each == "" {
    44  			continue
    45  		}
    46  		buffer.WriteString("/")
    47  		if strings.HasPrefix(each, "{") {
    48  			// check for regular expression in variable
    49  			colon := strings.Index(each, ":")
    50  			var varName string
    51  			if colon != -1 {
    52  				// extract expression
    53  				varName = strings.TrimSpace(each[1:colon])
    54  				paramExpr := strings.TrimSpace(each[colon+1 : len(each)-1])
    55  				if paramExpr == "*" { // special case
    56  					buffer.WriteString("(.*)")
    57  				} else {
    58  					buffer.WriteString(fmt.Sprintf("(%s)", paramExpr)) // between colon and closing moustache
    59  				}
    60  			} else {
    61  				// plain var
    62  				varName = strings.TrimSpace(each[1 : len(each)-1])
    63  				buffer.WriteString("([^/]+?)")
    64  			}
    65  			varNames = append(varNames, varName)
    66  			varCount += 1
    67  		} else {
    68  			literalCount += len(each)
    69  			encoded := each // TODO URI encode
    70  			buffer.WriteString(regexp.QuoteMeta(encoded))
    71  		}
    72  	}
    73  	return strings.TrimRight(buffer.String(), "/") + "(/.*)?$", literalCount, varNames, varCount, tokens
    74  }
    75  

View as plain text