mirror of https://github.com/harness/drone.git
[MISC] Extend support of URL Configuration (#645)
parent
d83552f288
commit
7334c4b8ed
|
@ -39,6 +39,11 @@ import (
|
|||
"golang.org/x/text/unicode/norm"
|
||||
)
|
||||
|
||||
const (
|
||||
schemeHTTP = "http"
|
||||
schemeHTTPS = "https"
|
||||
)
|
||||
|
||||
// LoadConfig returns the system configuration from the
|
||||
// host environment.
|
||||
func LoadConfig() (*types.Config, error) {
|
||||
|
@ -61,18 +66,24 @@ func LoadConfig() (*types.Config, error) {
|
|||
return config, nil
|
||||
}
|
||||
|
||||
//nolint:gocognit // refactor if required
|
||||
func backfillURLs(config *types.Config) error {
|
||||
// default base url
|
||||
scheme, host, port, path := "http", "localhost", fmt.Sprint(config.Server.HTTP.Port), ""
|
||||
// TODO: once we actually use the config.Server.HTTP.Proto, we have to update that here.
|
||||
scheme, host, port, path := schemeHTTP, "localhost", "", ""
|
||||
|
||||
// TODO: handle https of server bind
|
||||
// by default drop scheme's default port
|
||||
if (scheme != schemeHTTP || config.Server.HTTP.Port != 80) &&
|
||||
(scheme != schemeHTTPS || config.Server.HTTP.Port != 443) {
|
||||
port = fmt.Sprint(config.Server.HTTP.Port)
|
||||
}
|
||||
|
||||
// backfil internal URLS before continuing override with user provided base (which is external facing)
|
||||
if config.URL.Internal == "" {
|
||||
config.URL.Internal = fmt.Sprintf("%s://localhost:%s", scheme, port)
|
||||
config.URL.Internal = combineToRawURL(scheme, "localhost", port, "")
|
||||
}
|
||||
if config.URL.Container == "" {
|
||||
config.URL.Container = fmt.Sprintf("%s://host.docker.internal:%s", scheme, port)
|
||||
config.URL.Container = combineToRawURL(scheme, "host.docker.internal", port, "")
|
||||
}
|
||||
|
||||
// override base with whatever user explicit override
|
||||
|
@ -82,23 +93,30 @@ func backfillURLs(config *types.Config) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("failed to parse base url '%s': %w", config.URL.Base, err)
|
||||
}
|
||||
if u.Scheme != "" {
|
||||
scheme = u.Scheme
|
||||
if u.Scheme != schemeHTTP && u.Scheme != schemeHTTPS {
|
||||
return fmt.Errorf(
|
||||
"base url scheme '%s' is not supported (valid values: %v)",
|
||||
u.Scheme,
|
||||
[]string{
|
||||
schemeHTTP,
|
||||
schemeHTTPS,
|
||||
},
|
||||
)
|
||||
}
|
||||
if u.Hostname() != "" {
|
||||
host = u.Hostname()
|
||||
}
|
||||
if u.Port() != "" {
|
||||
port = u.Port()
|
||||
}
|
||||
if u.Path != "" {
|
||||
// ensure path starts with a slash (so we only add slash if path is provided)
|
||||
path = "/" + strings.Trim(u.Path, "/")
|
||||
// url parsing allows empty hostname - we don't want that
|
||||
if u.Hostname() == "" {
|
||||
return fmt.Errorf("a non-empty base url host has to be provided")
|
||||
}
|
||||
|
||||
// take everything as is (e.g. if user explicitly adds port 80 for http we take it)
|
||||
scheme = u.Scheme
|
||||
host = u.Hostname()
|
||||
port = u.Port()
|
||||
path = u.Path
|
||||
}
|
||||
|
||||
// create base URL object
|
||||
baseURLRaw := fmt.Sprintf("%s://%s:%s%s", scheme, host, port, path)
|
||||
baseURLRaw := combineToRawURL(scheme, host, port, path)
|
||||
baseURL, err := url.Parse(baseURLRaw)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse derived base url '%s': %w", baseURLRaw, err)
|
||||
|
@ -118,6 +136,23 @@ func backfillURLs(config *types.Config) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func combineToRawURL(scheme, host, port, path string) string {
|
||||
urlRAW := scheme + "://" + host
|
||||
|
||||
// only add port if explicitly provided
|
||||
if port != "" {
|
||||
urlRAW += ":" + port
|
||||
}
|
||||
|
||||
// only add path if it's not empty and non-root
|
||||
path = strings.Trim(path, "/")
|
||||
if path != "" {
|
||||
urlRAW += "/" + path
|
||||
}
|
||||
|
||||
return urlRAW
|
||||
}
|
||||
|
||||
// getSanitizedMachineName gets the name of the machine and returns it in sanitized format.
|
||||
func getSanitizedMachineName() (string, error) {
|
||||
// use the hostname as default id of the instance
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestBackfilURLsPortBind(t *testing.T) {
|
||||
func TestBackfillURLsHTTPPort(t *testing.T) {
|
||||
config := &types.Config{}
|
||||
config.Server.HTTP.Port = 1234
|
||||
|
||||
|
@ -37,7 +37,70 @@ func TestBackfilURLsPortBind(t *testing.T) {
|
|||
require.Equal(t, "http://localhost:1234", config.URL.UI)
|
||||
}
|
||||
|
||||
func TestBackfilURLsBase(t *testing.T) {
|
||||
func TestBackfillURLsHTTPPortStripsDefaultHTTP(t *testing.T) {
|
||||
config := &types.Config{}
|
||||
config.Server.HTTP.Port = 80
|
||||
|
||||
err := backfillURLs(config)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, "http://localhost", config.URL.Internal)
|
||||
require.Equal(t, "http://host.docker.internal", config.URL.Container)
|
||||
|
||||
require.Equal(t, "http://localhost/api", config.URL.API)
|
||||
require.Equal(t, "http://localhost/git", config.URL.Git)
|
||||
require.Equal(t, "http://localhost", config.URL.UI)
|
||||
}
|
||||
|
||||
// TODO: Update once we add proper https support - as of now nothing is stripped!
|
||||
func TestBackfillURLsHTTPPortStripsDefaultHTTPS(t *testing.T) {
|
||||
config := &types.Config{}
|
||||
config.Server.HTTP.Port = 443
|
||||
|
||||
err := backfillURLs(config)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, "http://localhost:443", config.URL.Internal)
|
||||
require.Equal(t, "http://host.docker.internal:443", config.URL.Container)
|
||||
|
||||
require.Equal(t, "http://localhost:443/api", config.URL.API)
|
||||
require.Equal(t, "http://localhost:443/git", config.URL.Git)
|
||||
require.Equal(t, "http://localhost:443", config.URL.UI)
|
||||
}
|
||||
|
||||
func TestBackfillURLsBaseInvalidProtocol(t *testing.T) {
|
||||
config := &types.Config{}
|
||||
config.URL.Base = "abc://xyz:4321/test"
|
||||
|
||||
err := backfillURLs(config)
|
||||
require.ErrorContains(t, err, "base url scheme 'abc' is not supported")
|
||||
}
|
||||
|
||||
func TestBackfillURLsBaseNoHost(t *testing.T) {
|
||||
config := &types.Config{}
|
||||
config.URL.Base = "http:///test"
|
||||
|
||||
err := backfillURLs(config)
|
||||
require.ErrorContains(t, err, "a non-empty base url host has to be provided")
|
||||
}
|
||||
|
||||
func TestBackfillURLsBaseNoHostWithPort(t *testing.T) {
|
||||
config := &types.Config{}
|
||||
config.URL.Base = "http://:4321/test"
|
||||
|
||||
err := backfillURLs(config)
|
||||
require.ErrorContains(t, err, "a non-empty base url host has to be provided")
|
||||
}
|
||||
|
||||
func TestBackfillURLsBaseInvalidPort(t *testing.T) {
|
||||
config := &types.Config{}
|
||||
config.URL.Base = "http://localhost:abc/test"
|
||||
|
||||
err := backfillURLs(config)
|
||||
require.ErrorContains(t, err, "invalid port \":abc\" after host")
|
||||
}
|
||||
|
||||
func TestBackfillURLsBase(t *testing.T) {
|
||||
config := &types.Config{}
|
||||
config.Server.HTTP.Port = 1234
|
||||
config.URL.Base = "https://xyz:4321/test"
|
||||
|
@ -53,23 +116,103 @@ func TestBackfilURLsBase(t *testing.T) {
|
|||
require.Equal(t, "https://xyz:4321/test", config.URL.UI)
|
||||
}
|
||||
|
||||
func TestBackfilURLsCustom(t *testing.T) {
|
||||
func TestBackfillURLsBaseDefaultPortHTTP(t *testing.T) {
|
||||
config := &types.Config{}
|
||||
config.Server.HTTP.Port = 1234
|
||||
config.URL.Base = "https://xyz:4321/test"
|
||||
config.URL.API = "http://API:1111/API/p"
|
||||
config.URL.Internal = "http://APIInternal:1111/APIInternal/p"
|
||||
config.URL.Git = "http://Git:1111/Git/p"
|
||||
config.URL.Container = "http://GitContainer:1111/GitContainer/p"
|
||||
config.URL.UI = "http://UI:1111/UI/p"
|
||||
config.URL.Base = "http://xyz/test"
|
||||
|
||||
err := backfillURLs(config)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, "http://APIInternal:1111/APIInternal/p", config.URL.Internal)
|
||||
require.Equal(t, "http://GitContainer:1111/GitContainer/p", config.URL.Container)
|
||||
require.Equal(t, "http://localhost:1234", config.URL.Internal)
|
||||
require.Equal(t, "http://host.docker.internal:1234", config.URL.Container)
|
||||
|
||||
require.Equal(t, "http://xyz/test/api", config.URL.API)
|
||||
require.Equal(t, "http://xyz/test/git", config.URL.Git)
|
||||
require.Equal(t, "http://xyz/test", config.URL.UI)
|
||||
}
|
||||
|
||||
func TestBackfillURLsBaseDefaultPortHTTPExplicit(t *testing.T) {
|
||||
config := &types.Config{}
|
||||
config.Server.HTTP.Port = 1234
|
||||
config.URL.Base = "http://xyz:80/test"
|
||||
|
||||
err := backfillURLs(config)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, "http://localhost:1234", config.URL.Internal)
|
||||
require.Equal(t, "http://host.docker.internal:1234", config.URL.Container)
|
||||
|
||||
require.Equal(t, "http://xyz:80/test/api", config.URL.API)
|
||||
require.Equal(t, "http://xyz:80/test/git", config.URL.Git)
|
||||
require.Equal(t, "http://xyz:80/test", config.URL.UI)
|
||||
}
|
||||
|
||||
func TestBackfillURLsBaseDefaultPortHTTPS(t *testing.T) {
|
||||
config := &types.Config{}
|
||||
config.Server.HTTP.Port = 1234
|
||||
config.URL.Base = "https://xyz/test"
|
||||
|
||||
err := backfillURLs(config)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, "http://localhost:1234", config.URL.Internal)
|
||||
require.Equal(t, "http://host.docker.internal:1234", config.URL.Container)
|
||||
|
||||
require.Equal(t, "https://xyz/test/api", config.URL.API)
|
||||
require.Equal(t, "https://xyz/test/git", config.URL.Git)
|
||||
require.Equal(t, "https://xyz/test", config.URL.UI)
|
||||
}
|
||||
|
||||
func TestBackfillURLsBaseDefaultPortHTTPSExplicit(t *testing.T) {
|
||||
config := &types.Config{}
|
||||
config.Server.HTTP.Port = 1234
|
||||
config.URL.Base = "https://xyz:443/test"
|
||||
|
||||
err := backfillURLs(config)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, "http://localhost:1234", config.URL.Internal)
|
||||
require.Equal(t, "http://host.docker.internal:1234", config.URL.Container)
|
||||
|
||||
require.Equal(t, "https://xyz:443/test/api", config.URL.API)
|
||||
require.Equal(t, "https://xyz:443/test/git", config.URL.Git)
|
||||
require.Equal(t, "https://xyz:443/test", config.URL.UI)
|
||||
}
|
||||
|
||||
func TestBackfillURLsBaseRootPathStripped(t *testing.T) {
|
||||
config := &types.Config{}
|
||||
config.Server.HTTP.Port = 1234
|
||||
config.URL.Base = "https://xyz:4321/"
|
||||
|
||||
err := backfillURLs(config)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, "http://localhost:1234", config.URL.Internal)
|
||||
require.Equal(t, "http://host.docker.internal:1234", config.URL.Container)
|
||||
|
||||
require.Equal(t, "https://xyz:4321/api", config.URL.API)
|
||||
require.Equal(t, "https://xyz:4321/git", config.URL.Git)
|
||||
require.Equal(t, "https://xyz:4321", config.URL.UI)
|
||||
}
|
||||
|
||||
func TestBackfillURLsCustom(t *testing.T) {
|
||||
config := &types.Config{}
|
||||
config.Server.HTTP.Port = 1234
|
||||
config.URL.Internal = "http://APIInternal/APIInternal/p"
|
||||
config.URL.Container = "https://GitContainer/GitContainer/p"
|
||||
config.URL.Base = "https://xyz:4321/test"
|
||||
config.URL.API = "http://API:1111/API/p"
|
||||
config.URL.Git = "https://Git:443/Git/p"
|
||||
config.URL.UI = "http://UI:80/UI/p"
|
||||
|
||||
err := backfillURLs(config)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, "http://APIInternal/APIInternal/p", config.URL.Internal)
|
||||
require.Equal(t, "https://GitContainer/GitContainer/p", config.URL.Container)
|
||||
|
||||
require.Equal(t, "http://API:1111/API/p", config.URL.API)
|
||||
require.Equal(t, "http://Git:1111/Git/p", config.URL.Git)
|
||||
require.Equal(t, "http://UI:1111/UI/p", config.URL.UI)
|
||||
require.Equal(t, "https://Git:443/Git/p", config.URL.Git)
|
||||
require.Equal(t, "http://UI:80/UI/p", config.URL.UI)
|
||||
}
|
||||
|
|
11
web/dist.go
11
web/dist.go
|
@ -38,6 +38,8 @@ var UI embed.FS
|
|||
|
||||
// Handler returns an http.HandlerFunc that servers the
|
||||
// static content from the embedded file system.
|
||||
//
|
||||
//nolint:gocognit // refactor if required.
|
||||
func Handler() http.HandlerFunc {
|
||||
// Load the files subdirectory
|
||||
fs, err := fs.Sub(UI, "dist")
|
||||
|
@ -56,9 +58,12 @@ func Handler() http.HandlerFunc {
|
|||
// we need to always load the index.html file
|
||||
// in the root of the project, unless the path
|
||||
// points to a file with an extension (css, js, etc)
|
||||
if filepath.Ext(r.URL.Path) == "" || // No ext: (1) a browser URL request, not a static asset request
|
||||
(strings.Contains(r.URL.Path, "...") && // "..." : (2a) browser URL with ... in it
|
||||
filepath.Ext(strings.ReplaceAll(r.URL.Path, "...", "")) == "") { // (2b) filter out static asset URLs that browsers make along with it
|
||||
// No ext: (1) a browser URL request, not a static asset request
|
||||
if filepath.Ext(r.URL.Path) == "" ||
|
||||
// "..." : (2a) browser URL with ... in it
|
||||
(strings.Contains(r.URL.Path, "...") &&
|
||||
// (2b) filter out static asset URLs that browsers make along with it
|
||||
filepath.Ext(strings.ReplaceAll(r.URL.Path, "...", "")) == "") {
|
||||
// HACK: alter the path to point to the
|
||||
// root of the project.
|
||||
r.URL.Path = "/"
|
||||
|
|
Loading…
Reference in New Issue