Skip to content

Commit cd3e7f2

Browse files
committed
Fix e.File() being picky with relative paths after 4.7.0 introduced echo.Fs support (Go1.16+)
1 parent 5ebed44 commit cd3e7f2

File tree

3 files changed

+102
-6
lines changed

3 files changed

+102
-6
lines changed

echo_fs_go1.16.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ func newDefaultFS() *defaultFS {
113113
}
114114

115115
func (fs defaultFS) Open(name string) (fs.File, error) {
116-
return fs.fs.Open(name)
116+
return fs.fs.Open(filepath.ToSlash(filepath.Clean(name)))
117117
}
118118

119119
func subFS(currentFs fs.FS, root string) (fs.FS, error) {

echo_fs_go1.16_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,3 +263,48 @@ func TestEcho_StaticPanic(t *testing.T) {
263263
})
264264
}
265265
}
266+
267+
func TestEchoStatic16(t *testing.T) { // when we drop Go1.15 support merge these testcases with `TestEchoStatic()`
268+
var testCases = []struct {
269+
name string
270+
givenPrefix string
271+
givenRoot string
272+
whenURL string
273+
expectStatus int
274+
expectHeaderLocation string
275+
expectBodyStartsWith string
276+
}{
277+
{ // `e.Static` is not meant to work by pointing `root` to file. This would be insecure.
278+
name: "nok, should not work when relative path for root points to file",
279+
givenPrefix: "/images",
280+
givenRoot: "./_fixture/images/walle.png",
281+
whenURL: "/images",
282+
expectStatus: http.StatusNotFound,
283+
expectBodyStartsWith: "{\"message\":\"Not Found\"}\n",
284+
},
285+
}
286+
287+
for _, tc := range testCases {
288+
t.Run(tc.name, func(t *testing.T) {
289+
e := New()
290+
e.Static(tc.givenPrefix, tc.givenRoot)
291+
req := httptest.NewRequest(http.MethodGet, tc.whenURL, nil)
292+
rec := httptest.NewRecorder()
293+
e.ServeHTTP(rec, req)
294+
assert.Equal(t, tc.expectStatus, rec.Code)
295+
body := rec.Body.String()
296+
if tc.expectBodyStartsWith != "" {
297+
assert.True(t, strings.HasPrefix(body, tc.expectBodyStartsWith))
298+
} else {
299+
assert.Equal(t, "", body)
300+
}
301+
302+
if tc.expectHeaderLocation != "" {
303+
assert.Equal(t, tc.expectHeaderLocation, rec.Result().Header["Location"][0])
304+
} else {
305+
_, ok := rec.Result().Header["Location"]
306+
assert.False(t, ok)
307+
}
308+
})
309+
}
310+
}

echo_test.go

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,14 @@ func TestEchoStatic(t *testing.T) {
8484
expectStatus: http.StatusOK,
8585
expectBodyStartsWith: string([]byte{0x89, 0x50, 0x4e, 0x47}),
8686
},
87+
{
88+
name: "ok with relative path for root points to directory",
89+
givenPrefix: "/images",
90+
givenRoot: "./_fixture/images",
91+
whenURL: "/images/walle.png",
92+
expectStatus: http.StatusOK,
93+
expectBodyStartsWith: string([]byte{0x89, 0x50, 0x4e, 0x47}),
94+
},
8795
{
8896
name: "No file",
8997
givenPrefix: "/images",
@@ -246,11 +254,54 @@ func TestEchoStaticRedirectIndex(t *testing.T) {
246254
}
247255

248256
func TestEchoFile(t *testing.T) {
249-
e := New()
250-
e.File("/walle", "_fixture/images/walle.png")
251-
c, b := request(http.MethodGet, "/walle", e)
252-
assert.Equal(t, http.StatusOK, c)
253-
assert.NotEmpty(t, b)
257+
var testCases = []struct {
258+
name string
259+
givenPath string
260+
givenFile string
261+
whenPath string
262+
expectCode int
263+
expectStartsWith string
264+
}{
265+
{
266+
name: "ok",
267+
givenPath: "/walle",
268+
givenFile: "_fixture/images/walle.png",
269+
whenPath: "/walle",
270+
expectCode: http.StatusOK,
271+
expectStartsWith: string([]byte{0x89, 0x50, 0x4e}),
272+
},
273+
{
274+
name: "ok with relative path",
275+
givenPath: "/",
276+
givenFile: "./go.mod",
277+
whenPath: "/",
278+
expectCode: http.StatusOK,
279+
expectStartsWith: "module github.com/labstack/echo/v",
280+
},
281+
{
282+
name: "nok file does not exist",
283+
givenPath: "/",
284+
givenFile: "./this-file-does-not-exist",
285+
whenPath: "/",
286+
expectCode: http.StatusNotFound,
287+
expectStartsWith: "{\"message\":\"Not Found\"}\n",
288+
},
289+
}
290+
291+
for _, tc := range testCases {
292+
t.Run(tc.name, func(t *testing.T) {
293+
e := New() // we are using echo.defaultFS instance
294+
e.File(tc.givenPath, tc.givenFile)
295+
296+
c, b := request(http.MethodGet, tc.whenPath, e)
297+
assert.Equal(t, tc.expectCode, c)
298+
299+
if len(b) > len(tc.expectStartsWith) {
300+
b = b[:len(tc.expectStartsWith)]
301+
}
302+
assert.Equal(t, tc.expectStartsWith, b)
303+
})
304+
}
254305
}
255306

256307
func TestEchoMiddleware(t *testing.T) {

0 commit comments

Comments
 (0)