mirror of
				https://github.com/owncast/owncast.git
				synced 2025-10-31 10:08:10 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			70 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			70 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package utils
 | |
| 
 | |
| import (
 | |
| 	"errors"
 | |
| 	"fmt"
 | |
| 	"net/http"
 | |
| 	"strings"
 | |
| )
 | |
| 
 | |
| const restURLPatternHeaderKey = "Owncast-Resturl-Pattern"
 | |
| 
 | |
| // takes the segment pattern of an Url string and returns the segment before the first dynamic REST parameter.
 | |
| func getPatternForRestEndpoint(pattern string) string {
 | |
| 	firstIndex := strings.Index(pattern, "/{")
 | |
| 	if firstIndex == -1 {
 | |
| 		return pattern
 | |
| 	}
 | |
| 
 | |
| 	return strings.TrimRight(pattern[:firstIndex], "/") + "/"
 | |
| }
 | |
| 
 | |
| func zip2D(iterable1 *[]string, iterable2 *[]string) map[string]string {
 | |
| 	dict := make(map[string]string)
 | |
| 	for index, key := range *iterable1 {
 | |
| 		dict[key] = (*iterable2)[index]
 | |
| 	}
 | |
| 	return dict
 | |
| }
 | |
| 
 | |
| func mapPatternWithRequestURL(pattern string, requestURL string) (map[string]string, error) {
 | |
| 	patternSplit := strings.Split(pattern, "/")
 | |
| 	requestURLSplit := strings.Split(requestURL, "/")
 | |
| 
 | |
| 	if len(patternSplit) == len(requestURLSplit) {
 | |
| 		return zip2D(&patternSplit, &requestURLSplit), nil
 | |
| 	}
 | |
| 	return nil, errors.New("the length of pattern and request Url does not match")
 | |
| }
 | |
| 
 | |
| func readParameter(pattern string, requestURL string, paramName string) (string, error) {
 | |
| 	all, err := mapPatternWithRequestURL(pattern, requestURL)
 | |
| 	if err != nil {
 | |
| 		return "", err
 | |
| 	}
 | |
| 
 | |
| 	if value, exists := all[fmt.Sprintf("{%s}", paramName)]; exists {
 | |
| 		return value, nil
 | |
| 	}
 | |
| 	return "", fmt.Errorf("parameter with name %s not found", paramName)
 | |
| }
 | |
| 
 | |
| // ReadRestURLParameter will return the parameter from the request of the requested name.
 | |
| func ReadRestURLParameter(r *http.Request, parameterName string) (string, error) {
 | |
| 	pattern, found := r.Header[restURLPatternHeaderKey]
 | |
| 	if !found {
 | |
| 		return "", fmt.Errorf("this HandlerFunc is not marked as REST-Endpoint. Cannot read Parameter '%s' from Request", parameterName)
 | |
| 	}
 | |
| 
 | |
| 	return readParameter(pattern[0], r.URL.Path, parameterName)
 | |
| }
 | |
| 
 | |
| // RestEndpoint wraps a handler to use the rest endpoint helper.
 | |
| func RestEndpoint(pattern string, handler http.HandlerFunc) (string, http.HandlerFunc) {
 | |
| 	baseURL := getPatternForRestEndpoint(pattern)
 | |
| 	return baseURL, func(w http.ResponseWriter, r *http.Request) {
 | |
| 		r.Header[restURLPatternHeaderKey] = []string{pattern}
 | |
| 		handler(w, r)
 | |
| 	}
 | |
| }
 | 
