labstack / echo

High performance, minimalist Go web framework

Home Page:https://echo.labstack.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Static file has wrong body returned when using a custom HTTP Error Handler and complex paths

alexferl opened this issue · comments

Issue Description

As per the title, I have a static CSS file that is correctly served when linked from an HTML template in a regular route, but the wrong body of the static CSS file is returned when used from a custom HTTP Error Handler. If I try to access a path that doesn't exist, /foo for example, everything works. It's when I try to access a path like /foo/bar that the static CSS file now has the wrong body.

See code and steps to reproduce, will be very clear.

Checklist

  • Dependencies installed
  • No typos
  • Searched existing issues and docs

Expected behaviour

The static file (main.css in this case) should always be returned correctly.

Actual behaviour

The static file (main.css in this case) has the same body as the HTML template.

Steps to reproduce

  1. go run main.go
  2. Visit http://localhost:1323/foo, notice the background is correctly light blue.
Screenshot 2024-01-24 at 14 43 35
  1. Visit http://localhost:1323/foo/bar, notice the background isn't light blue anymore because the body of main.css is the same as the 4xx template.
Screenshot 2024-01-24 at 14 43 21

Working code to debug

main.go:

package main

import (
	"fmt"
	"net/http"

	"github.com/alexferl/echo-multitemplate"
	"github.com/labstack/echo/v4"
)

func errorHandler(err error, c echo.Context) {
	if err := c.Render(http.StatusOK, "4xx", nil); err != nil {
		fmt.Printf("error: %v", err)
	}
}

func main() {
	e := echo.New()
	e.Static("/static", "static")
	e.HTTPErrorHandler = errorHandler

	r := multitemplate.New()
	r.AddFromFiles("4xx", "templates/base.gohtml", "templates/4xx.gohtml")
	e.Renderer = r

	e.GET("/", func(c echo.Context) error {
		return c.String(http.StatusOK, "index")
	})

	e.Logger.Fatal(e.Start("localhost:1323"))
}

templates/base.gohtml:

<!DOCTYPE html>
<html>
<head>
    <link href="./static/main.css" rel="stylesheet">
</head>
<body>
{{ template "content" . }}
</body>
</html>

templates/4xx.gohtml

{{ define "content" }}4xx{{ end }}

static/main.css:

body {
    background-color: lightblue;
}

Version/commit

v4.11.4

This is because <link href="./static/main.css" rel="stylesheet"> is includes css file from relative path by browser (check the URL browser is requesting tha css file).
When you request http://localhost:1323/foo the relative path is / and then you request http://localhost:1323/foo/bar the path is /foo/

change it to <link href="/static/main.css" rel="stylesheet"> so browser will use "static" absolute path for request that does not depend on the current path.

@aldas, indeed it works correctly without the . thank you!