Skip to content

Commit 827e135

Browse files
authored
Merge pull request #3883 from DanielLeone/fix_base_url_no_longer_working
fix for the base URL server replacement
2 parents 2507956 + fa0f116 commit 827e135

File tree

4 files changed

+78
-57
lines changed

4 files changed

+78
-57
lines changed

backend/cmd/headlamp.go

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -126,35 +126,27 @@ func fileExists(filename string) bool {
126126
return !info.IsDir()
127127
}
128128

129-
// copy a file, whilst doing some search/replace on the data.
130-
func copyReplace(src string, dst string,
131-
search []byte, replace []byte,
132-
search2 []byte, replace2 []byte,
133-
) {
134-
data, err := os.ReadFile(src)
129+
func mustReadFile(path string) []byte {
130+
data, err := os.ReadFile(path)
135131
if err != nil {
136132
// Error Reading the file
137133
logger.Log(logger.LevelError, nil, err, "reading file")
138134
os.Exit(1)
139135
}
140136

141-
data1 := bytes.ReplaceAll(data, search, replace)
142-
data2 := bytes.ReplaceAll(data1, search2, replace2)
143-
fileMode := 0o600
137+
return data
138+
}
144139

145-
err = os.WriteFile(dst, data2, fs.FileMode(fileMode))
140+
func mustWriteFile(path string, data []byte) {
141+
err := os.WriteFile(path, data, fs.FileMode(0o600))
146142
if err != nil {
147143
// Error writing the file
148144
logger.Log(logger.LevelError, nil, err, "writing file")
149145
os.Exit(1)
150146
}
151147
}
152148

153-
// make sure the base-url is updated in the index.html file.
154-
func baseURLReplace(staticDir string, baseURL string) {
155-
indexBaseURL := path.Join(staticDir, "index.baseUrl.html")
156-
index := path.Join(staticDir, "index.html")
157-
149+
func makeBaseURLReplacements(data []byte, baseURL string) []byte {
158150
replaceURL := baseURL
159151
if baseURL == "" {
160152
// We have to do the replace when baseURL == "" because of the case when
@@ -163,20 +155,45 @@ func baseURLReplace(staticDir string, baseURL string) {
163155
replaceURL = "/"
164156
}
165157

166-
if !fileExists(indexBaseURL) {
167-
copyReplace(index, indexBaseURL, []byte(""), []byte(""), []byte(""), []byte(""))
168-
}
158+
// Replacement for headlampBaseUrl - matched from the known index.html content
159+
data = bytes.ReplaceAll(
160+
data,
161+
[]byte("headlampBaseUrl = __baseUrl__"),
162+
[]byte(fmt.Sprintf("headlampBaseUrl = '%s'", replaceURL)),
163+
)
169164

170-
copyReplace(indexBaseURL,
171-
index,
172-
[]byte("headlampBaseUrl = './'"),
173-
[]byte("headlampBaseUrl = '"+replaceURL+"'"),
174-
// Replace any resource that has "./" in it
165+
// Replace any resource that has "./" in it
166+
data = bytes.ReplaceAll(
167+
data,
175168
[]byte("./"),
176-
[]byte(baseURL+"/"))
169+
[]byte(fmt.Sprintf("%s/", baseURL)),
170+
)
177171

178172
// Insert baseURL in css url() imports, they don't have "./" in them
179-
copyReplace(index, index, []byte("url("), []byte("url("+baseURL+"/"), []byte(""), []byte(""))
173+
data = bytes.ReplaceAll(
174+
data,
175+
[]byte("url("),
176+
[]byte(fmt.Sprintf("url(%s/", baseURL)),
177+
)
178+
179+
return data
180+
}
181+
182+
// make sure the base-url is updated in the index.html file.
183+
func baseURLReplace(staticDir string, baseURL string) {
184+
indexBaseURL := path.Join(staticDir, "index.baseUrl.html")
185+
index := path.Join(staticDir, "index.html")
186+
187+
// keep a copy of the untouched index.html file as the source for replacements
188+
if !fileExists(indexBaseURL) {
189+
d := mustReadFile(index)
190+
mustWriteFile(indexBaseURL, d)
191+
}
192+
193+
// replace baseURL starting from the original copy, incase we run this multiple times
194+
data := mustReadFile(indexBaseURL)
195+
output := makeBaseURLReplacements(data, baseURL)
196+
mustWriteFile(index, output)
180197
}
181198

182199
func getOidcCallbackURL(r *http.Request, config *HeadlampConfig) string {

backend/cmd/headlamp_test.go

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -769,35 +769,6 @@ func TestFileExists(t *testing.T) {
769769
"fileExists() should return false for directory")
770770
}
771771

772-
func TestCopyReplace(t *testing.T) {
773-
// Create temporary source and destination files
774-
srcFile, err := os.CreateTemp("", "src_file_*")
775-
require.NoError(t, err)
776-
777-
defer os.Remove(srcFile.Name())
778-
779-
dstFile, err := os.CreateTemp("", "dst_file_*")
780-
require.NoError(t, err)
781-
782-
defer os.Remove(dstFile.Name())
783-
784-
// Write test content to source file
785-
_, err = srcFile.WriteString("Hello, World! This is a test.")
786-
require.NoError(t, err)
787-
788-
srcFile.Close()
789-
790-
// Test successful copy and replace
791-
copyReplace(srcFile.Name(), dstFile.Name(),
792-
[]byte("Hello"), []byte("Hi"),
793-
[]byte("test"), []byte("example"))
794-
795-
dstContent, err := os.ReadFile(dstFile.Name())
796-
require.NoError(t, err)
797-
798-
assert.Equal(t, "Hi, World! This is a example.", string(dstContent), "copyReplace() should correctly replace content")
799-
}
800-
801772
//nolint:funlen
802773
func TestBaseURLReplace(t *testing.T) {
803774
// Create a temporary directory for testing
@@ -810,7 +781,7 @@ func TestBaseURLReplace(t *testing.T) {
810781
indexContent := []byte(`<!DOCTYPE html>
811782
<html>
812783
<head>
813-
<script>var headlampBaseUrl = './';</script>
784+
<script>var headlampBaseUrl = __baseUrl__;</script>
814785
<link rel="stylesheet" href="./styles.css">
815786
</head>
816787
<body>
@@ -874,6 +845,36 @@ func TestBaseURLReplace(t *testing.T) {
874845
}
875846
}
876847

848+
func TestBaseURLReplaceWithCurrentIndexHTMLContentAndRSPackBuild(t *testing.T) {
849+
// This is the current contents of index.html given the recent changes to support both rsbuild and webpack
850+
// after the front-end is built, one of the BASE_URL variables will have been replaced with string contents
851+
// depending on which build system was used. In either case though, if the server knows the base URL,
852+
// we want to ensure it is used, so headlampBaseUrl will be forced to the value we want
853+
output := makeBaseURLReplacements([]byte(`
854+
<!DOCTYPE html>
855+
<html>
856+
<head>
857+
<script>
858+
__baseUrl__ = '%BASE_URL%<%= BASE_URL %>'.replace('%BASE_' + 'URL%', '').replace('<' + '%= BASE_URL %>', '');
859+
headlampBaseUrl = __baseUrl__;
860+
</script>
861+
</head>
862+
</html>
863+
`), "/headlamp")
864+
865+
assert.Equal(t, string(output), `
866+
<!DOCTYPE html>
867+
<html>
868+
<head>
869+
<script>
870+
__baseUrl__ = '%BASE_URL%<%= BASE_URL %>'.replace('%BASE_' + 'URL%', '').replace('<' + '%= BASE_URL %>', '');
871+
headlampBaseUrl = '/headlamp';
872+
</script>
873+
</head>
874+
</html>
875+
`)
876+
}
877+
877878
func TestGetOidcCallbackURL(t *testing.T) {
878879
tests := []struct {
879880
name string

frontend/index.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@
2424
-->
2525
<title>Headlamp</title>
2626
<script>
27-
headlampBaseUrl = '%BASE_URL%<%= BASE_URL %>'.replace('%BASE_' + 'URL%', '').replace('<' + '%= BASE_URL %>', '');
27+
// handles both webpack and rspack build systems
28+
__baseUrl__ = '%BASE_URL%<%= BASE_URL %>'.replace('%BASE_' + 'URL%', '').replace('<' + '%= BASE_URL %>', '');
29+
// the syntax of the following line is special - it will be matched and replaced by the server if a base URL is set by the server
30+
headlampBaseUrl = __baseUrl__;
2831
</script>
2932
<style>
3033
.splash {

frontend/rsbuild.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export default defineConfig({
2525
html: {
2626
template: './index.html',
2727
templateParameters: {
28-
BASE_URL: process.env.BASE_URL || './',
28+
BASE_URL: process.env.BASE_URL || '/',
2929
},
3030
},
3131
server: {

0 commit comments

Comments
 (0)