1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- package restful
- import (
- "bytes"
- "strings"
- )
- // Copyright 2018 Ernest Micklei. All rights reserved.
- // Use of this source code is governed by a license
- // that can be found in the LICENSE file.
- // PathProcessor is extra behaviour that a Router can provide to extract path parameters from the path.
- // If a Router does not implement this interface then the default behaviour will be used.
- type PathProcessor interface {
- // ExtractParameters gets the path parameters defined in the route and webService from the urlPath
- ExtractParameters(route *Route, webService *WebService, urlPath string) map[string]string
- }
- type defaultPathProcessor struct{}
- // Extract the parameters from the request url path
- func (d defaultPathProcessor) ExtractParameters(r *Route, _ *WebService, urlPath string) map[string]string {
- urlParts := tokenizePath(urlPath)
- pathParameters := map[string]string{}
- for i, key := range r.pathParts {
- var value string
- if i >= len(urlParts) {
- value = ""
- } else {
- value = urlParts[i]
- }
- if r.hasCustomVerb && hasCustomVerb(key) {
- key = removeCustomVerb(key)
- value = removeCustomVerb(value)
- }
- if strings.Index(key, "{") > -1 { // path-parameter
- if colon := strings.Index(key, ":"); colon != -1 {
- // extract by regex
- regPart := key[colon+1 : len(key)-1]
- keyPart := key[1:colon]
- if regPart == "*" {
- pathParameters[keyPart] = untokenizePath(i, urlParts)
- break
- } else {
- pathParameters[keyPart] = value
- }
- } else {
- // without enclosing {}
- startIndex := strings.Index(key, "{")
- endKeyIndex := strings.Index(key, "}")
- suffixLength := len(key) - endKeyIndex - 1
- endValueIndex := len(value) - suffixLength
- pathParameters[key[startIndex+1:endKeyIndex]] = value[startIndex:endValueIndex]
- }
- }
- }
- return pathParameters
- }
- // Untokenize back into an URL path using the slash separator
- func untokenizePath(offset int, parts []string) string {
- var buffer bytes.Buffer
- for p := offset; p < len(parts); p++ {
- buffer.WriteString(parts[p])
- // do not end
- if p < len(parts)-1 {
- buffer.WriteString("/")
- }
- }
- return buffer.String()
- }
|