123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- 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 {
- var 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)
- }
- }
|