Repository navigation
Closed
Description
This code works in v4, but when run in v5, the browser says ERR_INVALID_RESPONSE
package main
import (
"encoding/csv"
"errors"
"log"
"net/http"
"os"
"strconv"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
)
type Item struct {
Name string
Price float64
Cost float64
}
func main() {
e := echo.New()
e.Use(middleware.RequestLogger())
e.Use(middleware.Gzip())
e.GET("/data.csv", func(c echo.Context) error {
items := []Item{
Item{
Name: "Item 1",
Price: 10.99,
Cost: 4.63,
},
Item{
Name: "Item 2",
Price: 20.99,
Cost: 12.82,
},
}
f, err := os.CreateTemp("/tmp/", "data-*.csv")
if err != nil {
e.Logger.Error("Could not create data temp file", err)
return c.HTML(500, "Could not create data temp file")
}
defer f.Close()
ic := csv.NewWriter(f)
ic.Write([]string{
"Name",
"Price",
"Cost"})
for _, item := range items {
row := []string{
item.Name,
strconv.FormatFloat(item.Price, 'f', 2, 64),
strconv.FormatFloat(item.Cost, 'f', 3, 64)}
ic.Write(row)
}
ic.Flush()
return c.Attachment(f.Name(), "data.csv")
})
if err := e.Start(":8080"); err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Fatal(err)
}
}
v5:
package main
import (
"encoding/csv"
"errors"
"log"
"net/http"
"os"
"strconv"
"github.com/labstack/echo/v5"
"github.com/labstack/echo/v5/middleware"
)
type Item struct {
Name string
Price float64
Cost float64
}
func main() {
e := echo.New()
e.Use(middleware.RequestLogger())
e.Use(middleware.Gzip())
e.GET("/data.csv", func(c *echo.Context) error {
items := []Item{
Item{
Name: "Item 1",
Price: 10.99,
Cost: 4.63,
},
Item{
Name: "Item 2",
Price: 20.99,
Cost: 12.82,
},
}
f, err := os.CreateTemp("/tmp/", "data-*.csv")
if err != nil {
e.Logger.Error("Could not create data temp file", err)
return c.HTML(500, "Could not create data temp file")
}
defer f.Close()
ic := csv.NewWriter(f)
ic.Write([]string{
"Name",
"Price",
"Cost"})
for _, item := range items {
row := []string{
item.Name,
strconv.FormatFloat(item.Price, 'f', 2, 64),
strconv.FormatFloat(item.Cost, 'f', 3, 64)}
ic.Write(row)
}
ic.Flush()
return c.Attachment(f.Name(), "data.csv")
})
if err := e.Start(":8080"); err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Fatal(err)
}
}
Metadata
Metadata
Assignees
Labels
No labels
Activity
aldas commentedon Mar 30, 2026
in
v5the defaulte.Filesystemis set to CWD current working directory and file related methods need to take account that filepath need adjustingYou can set your filesystem to
/tmpwithand when you serve the file the path must be trimmed from
/tmpprefixaldas commentedon Mar 30, 2026
aldas commentedon Mar 30, 2026
I will investigate if we can similar tricks with default filesystem so dir prefix would not be that big annoyance
aldas commentedon Mar 31, 2026
@henderb I have modified defaultFS behavior so that
Opencan handle absolute path file names have matching prefix as filesystem. The default filesystem will still be initialized to CWD but now it easier to create fs can mimic more os.Open behavior.so if you would change fs to, you example would work.
I'll release new version today
henderb commentedon Mar 31, 2026
thanks, since I'm not sure what else might depend on the default filesystem path, I've changed my temp file creation from /tmp/ to tmp/ and it seems happy.
aldas commentedon Mar 31, 2026
@henderb
/tmpis cleaned on each restart under linux. but anyway you should not forget that files you are creating need to be removed somehow or you will run out of free space or inodes.henderb commentedon Mar 31, 2026
good point.
I think I'll be ok since fly.io doesn't keep files written outside mounted volumes across instance boots. Mine is scaling to zero very often. But could be a problem for later.
On dev, I'm rebuilding the container often enough or could have docker-compose map it somewhere in /tmp/my-app/