diff options
author | Runxi Yu <me@runxiyu.org> | 2025-04-05 19:45:17 +0800 |
---|---|---|
committer | Runxi Yu <me@runxiyu.org> | 2025-04-05 19:45:17 +0800 |
commit | 54a19febc0c7c49caa014254cabab571abad60ab (patch) | |
tree | a0b5ffe5aaaff956d5d41b09ca1d2127f771d17a /url.go | |
parent | git2c: Fix regression in potential integer overflow (diff) | |
download | forge-54a19febc0c7c49caa014254cabab571abad60ab.tar.gz forge-54a19febc0c7c49caa014254cabab571abad60ab.tar.zst forge-54a19febc0c7c49caa014254cabab571abad60ab.zip |
misc: Move url.go into the misc package
Diffstat (limited to 'url.go')
-rw-r--r-- | url.go | 154 |
1 files changed, 0 insertions, 154 deletions
@@ -1,154 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -// SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org> - -package main - -import ( - "errors" - "net/http" - "net/url" - "strings" -) - -var ( - errDupRefSpec = errors.New("duplicate ref spec") - errNoRefSpec = errors.New("no ref spec") -) - -// getParamRefTypeName looks at the query parameters in an HTTP request and -// returns its ref name and type, if any. -func getParamRefTypeName(request *http.Request) (retRefType, retRefName string, err error) { - rawQuery := request.URL.RawQuery - queryValues, err := url.ParseQuery(rawQuery) - if err != nil { - return - } - done := false - for _, refType := range []string{"commit", "branch", "tag"} { - refName, ok := queryValues[refType] - if ok { - if done { - err = errDupRefSpec - return - } - done = true - if len(refName) != 1 { - err = errDupRefSpec - return - } - retRefName = refName[0] - retRefType = refType - } - } - if !done { - err = errNoRefSpec - } - return -} - -// parseReqURI parses an HTTP request URL, and returns a slice of path segments -// and the query parameters. It handles %2F correctly. -func parseReqURI(requestURI string) (segments []string, params url.Values, err error) { - path, paramsStr, _ := strings.Cut(requestURI, "?") - - segments, err = pathToSegments(path) - if err != nil { - return - } - - params, err = url.ParseQuery(paramsStr) - return -} - -func pathToSegments(path string) (segments []string, err error) { - segments = strings.Split(strings.TrimPrefix(path, "/"), "/") - - for i, segment := range segments { - segments[i], err = url.PathUnescape(segment) - if err != nil { - return - } - } - - return -} - -// redirectDir returns true and redirects the user to a version of the URL with -// a trailing slash, if and only if the request URL does not already have a -// trailing slash. -func redirectDir(writer http.ResponseWriter, request *http.Request) bool { - requestURI := request.RequestURI - - pathEnd := strings.IndexAny(requestURI, "?#") - var path, rest string - if pathEnd == -1 { - path = requestURI - } else { - path = requestURI[:pathEnd] - rest = requestURI[pathEnd:] - } - - if !strings.HasSuffix(path, "/") { - http.Redirect(writer, request, path+"/"+rest, http.StatusSeeOther) - return true - } - return false -} - -// redirectNoDir returns true and redirects the user to a version of the URL -// without a trailing slash, if and only if the request URL has a trailing -// slash. -func redirectNoDir(writer http.ResponseWriter, request *http.Request) bool { - requestURI := request.RequestURI - - pathEnd := strings.IndexAny(requestURI, "?#") - var path, rest string - if pathEnd == -1 { - path = requestURI - } else { - path = requestURI[:pathEnd] - rest = requestURI[pathEnd:] - } - - if strings.HasSuffix(path, "/") { - http.Redirect(writer, request, strings.TrimSuffix(path, "/")+rest, http.StatusSeeOther) - return true - } - return false -} - -// redirectUnconditionally unconditionally redirects the user back to the -// current page while preserving query parameters. -func redirectUnconditionally(writer http.ResponseWriter, request *http.Request) { - requestURI := request.RequestURI - - pathEnd := strings.IndexAny(requestURI, "?#") - var path, rest string - if pathEnd == -1 { - path = requestURI - } else { - path = requestURI[:pathEnd] - rest = requestURI[pathEnd:] - } - - http.Redirect(writer, request, path+rest, http.StatusSeeOther) -} - -// segmentsToURL joins URL segments to the path component of a URL. -// Each segment is escaped properly first. -func segmentsToURL(segments []string) string { - for i, segment := range segments { - segments[i] = url.PathEscape(segment) - } - return strings.Join(segments, "/") -} - -// anyContain returns true if and only if ss contains a string that contains c. -func anyContain(ss []string, c string) bool { - for _, s := range ss { - if strings.Contains(s, c) { - return true - } - } - return false -} |