full diff: https://github.com/emicklei/go-restful/compare/v2.9.5...v3.7.3 - Switch to using go modules - Add check for wildcard to fix CORS filter - Add check on writer to prevent compression of response twice - Add OPTIONS shortcut WebService receiver - Add Route metadata to request attributes or allow adding attributes to routes - Add wroteHeader set - Enable content encoding on Handle and ServeHTTP - Feat: support google custom verb - Feature: override list of method allowed without content-type - Fix Allow header not set on '405: Method Not Allowed' responses - Fix Go 1.15: conversion from int to string yields a string of one rune - Fix WriteError return value - Fix: use request/response resulting from filter chain - handle path params with prefixes and suffixes - HTTP response body was broken, if struct to be converted to JSON has boolean value - List available representations in 406 body - Support describing response headers - Unwrap function in filter chain + remove unused dispatchWithFilters Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
		
			
				
	
	
		
			75 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			75 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
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()
 | 
						|
}
 |