Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions internal/utils/utils_str.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package utils
import (
"bytes"
"strings"
"unicode"
)

// DefaultTrimChars are the characters which are stripped by Trim* functions in default.
Expand Down Expand Up @@ -167,3 +168,13 @@ func StripSlashes(str string) string {
}
return buf.String()
}

// IsASCII checks whether given string is ASCII characters.
func IsASCII(s string) bool {
for i := 0; i < len(s); i++ {
if s[i] > unicode.MaxASCII {
return false
}
}
return true
}
10 changes: 10 additions & 0 deletions internal/utils/utils_z_unit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,13 @@ func Test_IsNumeric(t *testing.T) {
t.Assert(utils.IsNumeric("+.1"), false)
})
}

func TestIsASCII(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
t.AssertEQ(utils.IsASCII("test"), true)
t.AssertEQ(utils.IsASCII("测试"), false)
t.AssertEQ(utils.IsASCII("テスト"), false)
t.AssertEQ(utils.IsASCII("테스트"), false)
t.AssertEQ(utils.IsASCII("😁😭❤️😓"), false)
})
}
8 changes: 7 additions & 1 deletion net/ghttp/ghttp_response.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"net/url"
"time"

"github.com/gogf/gf/v2/internal/utils"
"github.com/gogf/gf/v2/net/ghttp/internal/response"
"github.com/gogf/gf/v2/net/gtrace"
"github.com/gogf/gf/v2/os/gfile"
Expand Down Expand Up @@ -89,7 +90,12 @@ func (r *Response) ServeFileDownload(path string, name ...string) {
}
r.Header().Set("Content-Type", "application/force-download")
r.Header().Set("Accept-Ranges", "bytes")
r.Header().Set("Content-Disposition", fmt.Sprintf(`attachment;filename=%s`, url.QueryEscape(downloadName)))
if utils.IsASCII(downloadName) {
r.Header().Set("Content-Disposition", fmt.Sprintf(`attachment;filename=%s`, url.QueryEscape(downloadName)))
} else {
r.Header().Set("Content-Disposition", fmt.Sprintf(`attachment;filename*=UTF-8''%s`, url.QueryEscape(downloadName)))
}

r.Header().Set("Access-Control-Expose-Headers", "Content-Disposition")
r.Server.serveFile(r.Request, serveFile)
}
Expand Down
12 changes: 12 additions & 0 deletions net/ghttp/ghttp_z_unit_feature_response_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package ghttp_test
import (
"fmt"
"net/http"
"net/url"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -81,6 +82,17 @@ func Test_Response_ServeFileDownload(t *testing.T) {
client.GetContent(ctx, "/ServeFileDownload", "filePath=files/server.key"),
"BEGIN RSA PRIVATE KEY"),
true)

resp, err := client.Get(ctx, "/ServeFileDownload", "filePath="+srcPath)
t.AssertNil(err)
t.Assert(resp.ReadAllString(), "file1.txt: This file is for uploading unit test case.")
t.Assert(resp.Header.Get("Content-Disposition"), "attachment;filename=file1.txt")

srcPath = gtest.DataPath("upload", "中文.txt")
resp, err = client.Get(ctx, "/ServeFileDownload", "filePath="+srcPath)
t.AssertNil(err)
t.Assert(resp.ReadAllString(), "中文.txt: This file is for uploading unit test case.")
t.Assert(resp.Header.Get("Content-Disposition"), "attachment;filename*=UTF-8''"+url.QueryEscape("中文.txt"))
})
}

Expand Down
1 change: 1 addition & 0 deletions net/ghttp/testdata/upload/中文.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
中文.txt: This file is for uploading unit test case.
Loading