mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-26 12:27:06 +00:00 
			
		
		
		
	Refactor AppURL usage (#30885)
Fix #30883 Fix #29591 --------- Co-authored-by: KN4CK3R <admin@oldschoolhack.me>
This commit is contained in:
		| @@ -4,6 +4,8 @@ | ||||
| package httplib | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"strings" | ||||
|  | ||||
| @@ -11,6 +13,10 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| ) | ||||
|  | ||||
| type RequestContextKeyStruct struct{} | ||||
|  | ||||
| var RequestContextKey = RequestContextKeyStruct{} | ||||
|  | ||||
| func urlIsRelative(s string, u *url.URL) bool { | ||||
| 	// Unfortunately browsers consider a redirect Location with preceding "//", "\\", "/\" and "\/" as meaning redirect to "http(s)://REST_OF_PATH" | ||||
| 	// Therefore we should ignore these redirect locations to prevent open redirects | ||||
| @@ -26,7 +32,56 @@ func IsRelativeURL(s string) bool { | ||||
| 	return err == nil && urlIsRelative(s, u) | ||||
| } | ||||
|  | ||||
| func IsCurrentGiteaSiteURL(s string) bool { | ||||
| func guessRequestScheme(req *http.Request, def string) string { | ||||
| 	// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto | ||||
| 	if s := req.Header.Get("X-Forwarded-Proto"); s != "" { | ||||
| 		return s | ||||
| 	} | ||||
| 	if s := req.Header.Get("X-Forwarded-Protocol"); s != "" { | ||||
| 		return s | ||||
| 	} | ||||
| 	if s := req.Header.Get("X-Url-Scheme"); s != "" { | ||||
| 		return s | ||||
| 	} | ||||
| 	if s := req.Header.Get("Front-End-Https"); s != "" { | ||||
| 		return util.Iif(s == "on", "https", "http") | ||||
| 	} | ||||
| 	if s := req.Header.Get("X-Forwarded-Ssl"); s != "" { | ||||
| 		return util.Iif(s == "on", "https", "http") | ||||
| 	} | ||||
| 	return def | ||||
| } | ||||
|  | ||||
| func guessForwardedHost(req *http.Request) string { | ||||
| 	// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host | ||||
| 	return req.Header.Get("X-Forwarded-Host") | ||||
| } | ||||
|  | ||||
| // GuessCurrentAppURL tries to guess the current full URL by http headers. It always has a '/' suffix, exactly the same as setting.AppURL | ||||
| func GuessCurrentAppURL(ctx context.Context) string { | ||||
| 	req, ok := ctx.Value(RequestContextKey).(*http.Request) | ||||
| 	if !ok { | ||||
| 		return setting.AppURL | ||||
| 	} | ||||
| 	if host := guessForwardedHost(req); host != "" { | ||||
| 		// if it is behind a reverse proxy, use "https" as default scheme in case the site admin forgets to set the correct forwarded-protocol headers | ||||
| 		return guessRequestScheme(req, "https") + "://" + host + setting.AppSubURL + "/" | ||||
| 	} else if req.Host != "" { | ||||
| 		// if it is not behind a reverse proxy, use the scheme from config options, meanwhile use "https" as much as possible | ||||
| 		defaultScheme := util.Iif(setting.Protocol == "http", "http", "https") | ||||
| 		return guessRequestScheme(req, defaultScheme) + "://" + req.Host + setting.AppSubURL + "/" | ||||
| 	} | ||||
| 	return setting.AppURL | ||||
| } | ||||
|  | ||||
| func MakeAbsoluteURL(ctx context.Context, s string) string { | ||||
| 	if IsRelativeURL(s) { | ||||
| 		return GuessCurrentAppURL(ctx) + strings.TrimPrefix(s, "/") | ||||
| 	} | ||||
| 	return s | ||||
| } | ||||
|  | ||||
| func IsCurrentGiteaSiteURL(ctx context.Context, s string) bool { | ||||
| 	u, err := url.Parse(s) | ||||
| 	if err != nil { | ||||
| 		return false | ||||
| @@ -45,5 +100,6 @@ func IsCurrentGiteaSiteURL(s string) bool { | ||||
| 	if u.Path == "" { | ||||
| 		u.Path = "/" | ||||
| 	} | ||||
| 	return strings.HasPrefix(strings.ToLower(u.String()), strings.ToLower(setting.AppURL)) | ||||
| 	urlLower := strings.ToLower(u.String()) | ||||
| 	return strings.HasPrefix(urlLower, strings.ToLower(setting.AppURL)) || strings.HasPrefix(urlLower, strings.ToLower(GuessCurrentAppURL(ctx))) | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 wxiaoguang
					wxiaoguang