Skip to content

Setup: empty prefix emits page-relative assets with root-relative handlers #163

Description

@linkdata

Summary

With an empty prefix, Jaws.Setup emits page-relative URLs for *staticserve.StaticServe resources but registers their handlers at root-relative paths. Assets work on / and 404 on nested pages.

Class / severity

Correctness — Medium. A JavaScript or CSS add-on can fail to load and leave a nested JaWS page nonfunctional.

Contract and valid usage

Jaws.Setup accepts *staticserve.StaticServe resources and an empty prefix. Empty prefix is explicitly covered by TestJaws_SetupEmptyPrefix; no documentation restricts that configuration to root pages. Serving a page such as /account/view is ordinary router use.

Reproduction

func TestSetupEmptyPrefixOnNestedPage(t *testing.T) {
	jw, err := jaws.New()
	if err != nil {
		t.Fatal(err)
	}
	defer jw.Close()

	mux := http.NewServeMux()
	asset := staticserve.Must("favicon.png", []byte("image"))
	if err := jw.Setup(mux.Handle, "", asset); err != nil {
		t.Fatal(err)
	}

	page, _ := url.Parse("http://example.test/account/view")
	ref, _ := url.Parse(jw.FaviconURL())
	resolved := page.ResolveReference(ref)

	rr := httptest.NewRecorder()
	mux.ServeHTTP(rr,
		httptest.NewRequest(http.MethodGet, resolved.String(), nil))

	if rr.Code != http.StatusOK {
		t.Fatalf("head URL %q resolves to %q: got %d",
			jw.FaviconURL(), resolved.Path, rr.Code)
	}
}

The emitted favicon.<hash>.png resolves to /account/favicon.<hash>.png; the registered route is /favicon.<hash>.png, so the response is 404.

Root cause

makeAbsPath adds a leading slash only when prefix != "". GenerateHeadHTML therefore emits a relative resource URL, while staticserve.NormalizeGET always registers an absolute handler pattern.

Impact

Root pages mask the defect. Nested pages fail to load configured favicon, CSS, and JavaScript resources.

Suggested fix

For locally served StaticServe resources, root the final path even when the prefix is empty so the emitted URL and registered handler use the same absolute path. Extend the existing empty-prefix test to assert URL/route equivalence from a nested page.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinggoPull requests that update go code

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions