mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-03 20:36:07 +01:00 
			
		
		
		
	Make ROOT_URL support using request Host header (#32564)
Resolve #32554 --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
		@@ -59,27 +59,16 @@ RUN_USER = ; git
 | 
				
			|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
					;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
				
			||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
					;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
				
			||||||
;;
 | 
					;;
 | 
				
			||||||
;; The protocol the server listens on. One of 'http', 'https', 'http+unix', 'fcgi' or 'fcgi+unix'. Defaults to 'http'
 | 
					;; The protocol the server listens on. One of "http", "https", "http+unix", "fcgi" or "fcgi+unix".
 | 
				
			||||||
;; Note: Value must be lowercase.
 | 
					 | 
				
			||||||
;PROTOCOL = http
 | 
					;PROTOCOL = http
 | 
				
			||||||
;;
 | 
					;;
 | 
				
			||||||
;; Expect PROXY protocol headers on connections
 | 
					;; Set the domain for the server.
 | 
				
			||||||
;USE_PROXY_PROTOCOL = false
 | 
					;; Most users should set it to the real website domain of their Gitea instance.
 | 
				
			||||||
;;
 | 
					 | 
				
			||||||
;; Use PROXY protocol in TLS Bridging mode
 | 
					 | 
				
			||||||
;PROXY_PROTOCOL_TLS_BRIDGING = false
 | 
					 | 
				
			||||||
;;
 | 
					 | 
				
			||||||
; Timeout to wait for PROXY protocol header (set to 0 to have no timeout)
 | 
					 | 
				
			||||||
;PROXY_PROTOCOL_HEADER_TIMEOUT=5s
 | 
					 | 
				
			||||||
;;
 | 
					 | 
				
			||||||
; Accept PROXY protocol headers with UNKNOWN type
 | 
					 | 
				
			||||||
;PROXY_PROTOCOL_ACCEPT_UNKNOWN=false
 | 
					 | 
				
			||||||
;;
 | 
					 | 
				
			||||||
;; Set the domain for the server
 | 
					 | 
				
			||||||
;DOMAIN = localhost
 | 
					;DOMAIN = localhost
 | 
				
			||||||
;;
 | 
					;;
 | 
				
			||||||
;; The AppURL used by Gitea to generate absolute links, defaults to "{PROTOCOL}://{DOMAIN}:{HTTP_PORT}/".
 | 
					;; The AppURL used by Gitea to generate absolute links, defaults to "{PROTOCOL}://{DOMAIN}:{HTTP_PORT}/".
 | 
				
			||||||
;; Most users should set it to the real website URL of their Gitea instance.
 | 
					;; Most users should set it to the real website URL of their Gitea instance when there is a reverse proxy.
 | 
				
			||||||
 | 
					;; When it is empty, Gitea will use HTTP "Host" header to generate ROOT_URL, and fall back to the default one if no "Host" header.
 | 
				
			||||||
;ROOT_URL =
 | 
					;ROOT_URL =
 | 
				
			||||||
;;
 | 
					;;
 | 
				
			||||||
;; For development purpose only. It makes Gitea handle sub-path ("/sub-path/owner/repo/...") directly when debugging without a reverse proxy.
 | 
					;; For development purpose only. It makes Gitea handle sub-path ("/sub-path/owner/repo/...") directly when debugging without a reverse proxy.
 | 
				
			||||||
@@ -90,13 +79,25 @@ RUN_USER = ; git
 | 
				
			|||||||
;STATIC_URL_PREFIX =
 | 
					;STATIC_URL_PREFIX =
 | 
				
			||||||
;;
 | 
					;;
 | 
				
			||||||
;; The address to listen on. Either a IPv4/IPv6 address or the path to a unix socket.
 | 
					;; The address to listen on. Either a IPv4/IPv6 address or the path to a unix socket.
 | 
				
			||||||
;; If PROTOCOL is set to `http+unix` or `fcgi+unix`, this should be the name of the Unix socket file to use.
 | 
					;; If PROTOCOL is set to "http+unix" or "fcgi+unix", this should be the name of the Unix socket file to use.
 | 
				
			||||||
;; Relative paths will be made absolute against the _`AppWorkPath`_.
 | 
					;; Relative paths will be made absolute against the _`AppWorkPath`_.
 | 
				
			||||||
;HTTP_ADDR = 0.0.0.0
 | 
					;HTTP_ADDR = 0.0.0.0
 | 
				
			||||||
;;
 | 
					;;
 | 
				
			||||||
;; The port to listen on. Leave empty when using a unix socket.
 | 
					;; The port to listen on for "http" or "https" protocol. Leave empty when using a unix socket.
 | 
				
			||||||
;HTTP_PORT = 3000
 | 
					;HTTP_PORT = 3000
 | 
				
			||||||
;;
 | 
					;;
 | 
				
			||||||
 | 
					;; Expect PROXY protocol headers on connections
 | 
				
			||||||
 | 
					;USE_PROXY_PROTOCOL = false
 | 
				
			||||||
 | 
					;;
 | 
				
			||||||
 | 
					;; Use PROXY protocol in TLS Bridging mode
 | 
				
			||||||
 | 
					;PROXY_PROTOCOL_TLS_BRIDGING = false
 | 
				
			||||||
 | 
					;;
 | 
				
			||||||
 | 
					;; Timeout to wait for PROXY protocol header (set to 0 to have no timeout)
 | 
				
			||||||
 | 
					;PROXY_PROTOCOL_HEADER_TIMEOUT = 5s
 | 
				
			||||||
 | 
					;;
 | 
				
			||||||
 | 
					;; Accept PROXY protocol headers with UNKNOWN type
 | 
				
			||||||
 | 
					;PROXY_PROTOCOL_ACCEPT_UNKNOWN = false
 | 
				
			||||||
 | 
					;;
 | 
				
			||||||
;; If REDIRECT_OTHER_PORT is true, and PROTOCOL is set to https an http server
 | 
					;; If REDIRECT_OTHER_PORT is true, and PROTOCOL is set to https an http server
 | 
				
			||||||
;; will be started on PORT_TO_REDIRECT and it will redirect plain, non-secure http requests to the main
 | 
					;; will be started on PORT_TO_REDIRECT and it will redirect plain, non-secure http requests to the main
 | 
				
			||||||
;; ROOT_URL.  Defaults are false for REDIRECT_OTHER_PORT and 80 for
 | 
					;; ROOT_URL.  Defaults are false for REDIRECT_OTHER_PORT and 80 for
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -70,11 +70,16 @@ func GuessCurrentHostURL(ctx context.Context) string {
 | 
				
			|||||||
	// 1. The reverse proxy is configured correctly, it passes "X-Forwarded-Proto/Host" headers. Perfect, Gitea can handle it correctly.
 | 
						// 1. The reverse proxy is configured correctly, it passes "X-Forwarded-Proto/Host" headers. Perfect, Gitea can handle it correctly.
 | 
				
			||||||
	// 2. The reverse proxy is not configured correctly, doesn't pass "X-Forwarded-Proto/Host" headers, eg: only one "proxy_pass http://gitea:3000" in Nginx.
 | 
						// 2. The reverse proxy is not configured correctly, doesn't pass "X-Forwarded-Proto/Host" headers, eg: only one "proxy_pass http://gitea:3000" in Nginx.
 | 
				
			||||||
	// 3. There is no reverse proxy.
 | 
						// 3. There is no reverse proxy.
 | 
				
			||||||
	// Without an extra config option, Gitea is impossible to distinguish between case 2 and case 3,
 | 
						// Without more information, Gitea is impossible to distinguish between case 2 and case 3, then case 2 would result in
 | 
				
			||||||
	// then case 2 would result in wrong guess like guessed AppURL becomes "http://gitea:3000/", which is not accessible by end users.
 | 
						// wrong guess like guessed AppURL becomes "http://gitea:3000/" behind a "https" reverse proxy, which is not accessible by end users.
 | 
				
			||||||
	// So in the future maybe it should introduce a new config option, to let site admin decide how to guess the AppURL.
 | 
						// So we introduced "UseHostHeader" option, it could be enabled by setting "ROOT_URL" to empty
 | 
				
			||||||
	reqScheme := getRequestScheme(req)
 | 
						reqScheme := getRequestScheme(req)
 | 
				
			||||||
	if reqScheme == "" {
 | 
						if reqScheme == "" {
 | 
				
			||||||
 | 
							// if no reverse proxy header, try to use "Host" header for absolute URL
 | 
				
			||||||
 | 
							if setting.UseHostHeader && req.Host != "" {
 | 
				
			||||||
 | 
								return util.Iif(req.TLS == nil, "http://", "https://") + req.Host
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// fall back to default AppURL
 | 
				
			||||||
		return strings.TrimSuffix(setting.AppURL, setting.AppSubURL+"/")
 | 
							return strings.TrimSuffix(setting.AppURL, setting.AppSubURL+"/")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// X-Forwarded-Host has many problems: non-standard, not well-defined (X-Forwarded-Port or not), conflicts with Host header.
 | 
						// X-Forwarded-Host has many problems: non-standard, not well-defined (X-Forwarded-Port or not), conflicts with Host header.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@ package httplib
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
 | 
						"crypto/tls"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -39,6 +40,25 @@ func TestIsRelativeURL(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestGuessCurrentHostURL(t *testing.T) {
 | 
				
			||||||
 | 
						defer test.MockVariableValue(&setting.AppURL, "http://cfg-host/sub/")()
 | 
				
			||||||
 | 
						defer test.MockVariableValue(&setting.AppSubURL, "/sub")()
 | 
				
			||||||
 | 
						defer test.MockVariableValue(&setting.UseHostHeader, false)()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx := t.Context()
 | 
				
			||||||
 | 
						assert.Equal(t, "http://cfg-host", GuessCurrentHostURL(ctx))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx = context.WithValue(ctx, RequestContextKey, &http.Request{Host: "localhost:3000"})
 | 
				
			||||||
 | 
						assert.Equal(t, "http://cfg-host", GuessCurrentHostURL(ctx))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						defer test.MockVariableValue(&setting.UseHostHeader, true)()
 | 
				
			||||||
 | 
						ctx = context.WithValue(ctx, RequestContextKey, &http.Request{Host: "http-host:3000"})
 | 
				
			||||||
 | 
						assert.Equal(t, "http://http-host:3000", GuessCurrentHostURL(ctx))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx = context.WithValue(ctx, RequestContextKey, &http.Request{Host: "http-host", TLS: &tls.ConnectionState{}})
 | 
				
			||||||
 | 
						assert.Equal(t, "https://http-host", GuessCurrentHostURL(ctx))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestMakeAbsoluteURL(t *testing.T) {
 | 
					func TestMakeAbsoluteURL(t *testing.T) {
 | 
				
			||||||
	defer test.MockVariableValue(&setting.Protocol, "http")()
 | 
						defer test.MockVariableValue(&setting.Protocol, "http")()
 | 
				
			||||||
	defer test.MockVariableValue(&setting.AppURL, "http://cfg-host/sub/")()
 | 
						defer test.MockVariableValue(&setting.AppURL, "http://cfg-host/sub/")()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,25 +46,37 @@ var (
 | 
				
			|||||||
	// AppURL is the Application ROOT_URL. It always has a '/' suffix
 | 
						// AppURL is the Application ROOT_URL. It always has a '/' suffix
 | 
				
			||||||
	// It maps to ini:"ROOT_URL"
 | 
						// It maps to ini:"ROOT_URL"
 | 
				
			||||||
	AppURL string
 | 
						AppURL string
 | 
				
			||||||
	// AppSubURL represents the sub-url mounting point for gitea. It is either "" or starts with '/' and ends without '/', such as '/{subpath}'.
 | 
					
 | 
				
			||||||
 | 
						// AppSubURL represents the sub-url mounting point for gitea, parsed from "ROOT_URL"
 | 
				
			||||||
 | 
						// It is either "" or starts with '/' and ends without '/', such as '/{sub-path}'.
 | 
				
			||||||
	// This value is empty if site does not have sub-url.
 | 
						// This value is empty if site does not have sub-url.
 | 
				
			||||||
	AppSubURL string
 | 
						AppSubURL string
 | 
				
			||||||
	// UseSubURLPath makes Gitea handle requests with sub-path like "/sub-path/owner/repo/...", to make it easier to debug sub-path related problems without a reverse proxy.
 | 
					
 | 
				
			||||||
 | 
						// UseSubURLPath makes Gitea handle requests with sub-path like "/sub-path/owner/repo/...",
 | 
				
			||||||
 | 
						// to make it easier to debug sub-path related problems without a reverse proxy.
 | 
				
			||||||
	UseSubURLPath bool
 | 
						UseSubURLPath bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// UseHostHeader makes Gitea prefer to use the "Host" request header for construction of absolute URLs.
 | 
				
			||||||
 | 
						UseHostHeader bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// AppDataPath is the default path for storing data.
 | 
						// AppDataPath is the default path for storing data.
 | 
				
			||||||
	// It maps to ini:"APP_DATA_PATH" in [server] and defaults to AppWorkPath + "/data"
 | 
						// It maps to ini:"APP_DATA_PATH" in [server] and defaults to AppWorkPath + "/data"
 | 
				
			||||||
	AppDataPath string
 | 
						AppDataPath string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// LocalURL is the url for locally running applications to contact Gitea. It always has a '/' suffix
 | 
						// LocalURL is the url for locally running applications to contact Gitea. It always has a '/' suffix
 | 
				
			||||||
	// It maps to ini:"LOCAL_ROOT_URL" in [server]
 | 
						// It maps to ini:"LOCAL_ROOT_URL" in [server]
 | 
				
			||||||
	LocalURL string
 | 
						LocalURL string
 | 
				
			||||||
	// AssetVersion holds a opaque value that is used for cache-busting assets
 | 
					
 | 
				
			||||||
 | 
						// AssetVersion holds an opaque value that is used for cache-busting assets
 | 
				
			||||||
	AssetVersion string
 | 
						AssetVersion string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	appTempPathInternal string // the temporary path for the app, it is only an internal variable, do not use it, always use AppDataTempDir
 | 
						// appTempPathInternal is the temporary path for the app, it is only an internal variable
 | 
				
			||||||
 | 
						// DO NOT use it directly, always use AppDataTempDir
 | 
				
			||||||
 | 
						appTempPathInternal string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Protocol                   Scheme
 | 
						Protocol                   Scheme
 | 
				
			||||||
	UseProxyProtocol           bool // `ini:"USE_PROXY_PROTOCOL"`
 | 
						UseProxyProtocol           bool
 | 
				
			||||||
	ProxyProtocolTLSBridging   bool //`ini:"PROXY_PROTOCOL_TLS_BRIDGING"`
 | 
						ProxyProtocolTLSBridging   bool
 | 
				
			||||||
	ProxyProtocolHeaderTimeout time.Duration
 | 
						ProxyProtocolHeaderTimeout time.Duration
 | 
				
			||||||
	ProxyProtocolAcceptUnknown bool
 | 
						ProxyProtocolAcceptUnknown bool
 | 
				
			||||||
	Domain                     string
 | 
						Domain                     string
 | 
				
			||||||
@@ -181,13 +193,14 @@ func loadServerFrom(rootCfg ConfigProvider) {
 | 
				
			|||||||
		EnableAcme = sec.Key("ENABLE_LETSENCRYPT").MustBool(false)
 | 
							EnableAcme = sec.Key("ENABLE_LETSENCRYPT").MustBool(false)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Protocol = HTTP
 | 
					 | 
				
			||||||
	protocolCfg := sec.Key("PROTOCOL").String()
 | 
						protocolCfg := sec.Key("PROTOCOL").String()
 | 
				
			||||||
	if protocolCfg != "https" && EnableAcme {
 | 
						if protocolCfg != "https" && EnableAcme {
 | 
				
			||||||
		log.Fatal("ACME could only be used with HTTPS protocol")
 | 
							log.Fatal("ACME could only be used with HTTPS protocol")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch protocolCfg {
 | 
						switch protocolCfg {
 | 
				
			||||||
 | 
						case "", "http":
 | 
				
			||||||
 | 
							Protocol = HTTP
 | 
				
			||||||
	case "https":
 | 
						case "https":
 | 
				
			||||||
		Protocol = HTTPS
 | 
							Protocol = HTTPS
 | 
				
			||||||
		if EnableAcme {
 | 
							if EnableAcme {
 | 
				
			||||||
@@ -243,7 +256,7 @@ func loadServerFrom(rootCfg ConfigProvider) {
 | 
				
			|||||||
		case "unix":
 | 
							case "unix":
 | 
				
			||||||
			log.Warn("unix PROTOCOL value is deprecated, please use http+unix")
 | 
								log.Warn("unix PROTOCOL value is deprecated, please use http+unix")
 | 
				
			||||||
			fallthrough
 | 
								fallthrough
 | 
				
			||||||
		case "http+unix":
 | 
							default: // "http+unix"
 | 
				
			||||||
			Protocol = HTTPUnix
 | 
								Protocol = HTTPUnix
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		UnixSocketPermissionRaw := sec.Key("UNIX_SOCKET_PERMISSION").MustString("666")
 | 
							UnixSocketPermissionRaw := sec.Key("UNIX_SOCKET_PERMISSION").MustString("666")
 | 
				
			||||||
@@ -256,6 +269,8 @@ func loadServerFrom(rootCfg ConfigProvider) {
 | 
				
			|||||||
		if !filepath.IsAbs(HTTPAddr) {
 | 
							if !filepath.IsAbs(HTTPAddr) {
 | 
				
			||||||
			HTTPAddr = filepath.Join(AppWorkPath, HTTPAddr)
 | 
								HTTPAddr = filepath.Join(AppWorkPath, HTTPAddr)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							log.Fatal("Invalid PROTOCOL %q", Protocol)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	UseProxyProtocol = sec.Key("USE_PROXY_PROTOCOL").MustBool(false)
 | 
						UseProxyProtocol = sec.Key("USE_PROXY_PROTOCOL").MustBool(false)
 | 
				
			||||||
	ProxyProtocolTLSBridging = sec.Key("PROXY_PROTOCOL_TLS_BRIDGING").MustBool(false)
 | 
						ProxyProtocolTLSBridging = sec.Key("PROXY_PROTOCOL_TLS_BRIDGING").MustBool(false)
 | 
				
			||||||
@@ -268,12 +283,16 @@ func loadServerFrom(rootCfg ConfigProvider) {
 | 
				
			|||||||
	PerWritePerKbTimeout = sec.Key("PER_WRITE_PER_KB_TIMEOUT").MustDuration(PerWritePerKbTimeout)
 | 
						PerWritePerKbTimeout = sec.Key("PER_WRITE_PER_KB_TIMEOUT").MustDuration(PerWritePerKbTimeout)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	defaultAppURL := string(Protocol) + "://" + Domain + ":" + HTTPPort
 | 
						defaultAppURL := string(Protocol) + "://" + Domain + ":" + HTTPPort
 | 
				
			||||||
	AppURL = sec.Key("ROOT_URL").MustString(defaultAppURL)
 | 
						AppURL = sec.Key("ROOT_URL").String()
 | 
				
			||||||
 | 
						if AppURL == "" {
 | 
				
			||||||
 | 
							UseHostHeader = true
 | 
				
			||||||
 | 
							AppURL = defaultAppURL
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Check validity of AppURL
 | 
						// Check validity of AppURL
 | 
				
			||||||
	appURL, err := url.Parse(AppURL)
 | 
						appURL, err := url.Parse(AppURL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Fatal("Invalid ROOT_URL '%s': %s", AppURL, err)
 | 
							log.Fatal("Invalid ROOT_URL %q: %s", AppURL, err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Remove default ports from AppURL.
 | 
						// Remove default ports from AppURL.
 | 
				
			||||||
	// (scheme-based URL normalization, RFC 3986 section 6.2.3)
 | 
						// (scheme-based URL normalization, RFC 3986 section 6.2.3)
 | 
				
			||||||
@@ -309,13 +328,15 @@ func loadServerFrom(rootCfg ConfigProvider) {
 | 
				
			|||||||
		defaultLocalURL = AppURL
 | 
							defaultLocalURL = AppURL
 | 
				
			||||||
	case FCGIUnix:
 | 
						case FCGIUnix:
 | 
				
			||||||
		defaultLocalURL = AppURL
 | 
							defaultLocalURL = AppURL
 | 
				
			||||||
	default:
 | 
						case HTTP, HTTPS:
 | 
				
			||||||
		defaultLocalURL = string(Protocol) + "://"
 | 
							defaultLocalURL = string(Protocol) + "://"
 | 
				
			||||||
		if HTTPAddr == "0.0.0.0" {
 | 
							if HTTPAddr == "0.0.0.0" {
 | 
				
			||||||
			defaultLocalURL += net.JoinHostPort("localhost", HTTPPort) + "/"
 | 
								defaultLocalURL += net.JoinHostPort("localhost", HTTPPort) + "/"
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			defaultLocalURL += net.JoinHostPort(HTTPAddr, HTTPPort) + "/"
 | 
								defaultLocalURL += net.JoinHostPort(HTTPAddr, HTTPPort) + "/"
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							log.Fatal("Invalid PROTOCOL %q", Protocol)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	LocalURL = sec.Key("LOCAL_ROOT_URL").MustString(defaultLocalURL)
 | 
						LocalURL = sec.Key("LOCAL_ROOT_URL").MustString(defaultLocalURL)
 | 
				
			||||||
	LocalURL = strings.TrimRight(LocalURL, "/") + "/"
 | 
						LocalURL = strings.TrimRight(LocalURL, "/") + "/"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -76,6 +76,7 @@ func TestShadowPassword(t *testing.T) {
 | 
				
			|||||||
func TestSelfCheckPost(t *testing.T) {
 | 
					func TestSelfCheckPost(t *testing.T) {
 | 
				
			||||||
	defer test.MockVariableValue(&setting.AppURL, "http://config/sub/")()
 | 
						defer test.MockVariableValue(&setting.AppURL, "http://config/sub/")()
 | 
				
			||||||
	defer test.MockVariableValue(&setting.AppSubURL, "/sub")()
 | 
						defer test.MockVariableValue(&setting.AppSubURL, "/sub")()
 | 
				
			||||||
 | 
						defer test.MockVariableValue(&setting.UseHostHeader, false)()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx, resp := contexttest.MockContext(t, "GET http://host/sub/admin/self_check?location_origin=http://frontend")
 | 
						ctx, resp := contexttest.MockContext(t, "GET http://host/sub/admin/self_check?location_origin=http://frontend")
 | 
				
			||||||
	SelfCheckPost(ctx)
 | 
						SelfCheckPost(ctx)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user