mirror of https://github.com/gin-gonic/gin.git
feat attachment filename support utf8 (#3071)
This commit is contained in:
parent
90330e2a76
commit
8860527de6
|
@ -6,7 +6,6 @@ package gin
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
|
@ -1018,7 +1017,11 @@ func (c *Context) FileFromFS(filepath string, fs http.FileSystem) {
|
|||
// FileAttachment writes the specified file into the body stream in an efficient way
|
||||
// On the client side, the file will typically be downloaded with the given filename
|
||||
func (c *Context) FileAttachment(filepath, filename string) {
|
||||
c.Writer.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", filename))
|
||||
if isASCII(filename) {
|
||||
c.Writer.Header().Set("Content-Disposition", `attachment; filename="`+filename+`"`)
|
||||
} else {
|
||||
c.Writer.Header().Set("Content-Disposition", `attachment; filename*=UTF-8''`+url.QueryEscape(filename))
|
||||
}
|
||||
http.ServeFile(c.Writer, c.Request, filepath)
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
@ -1033,6 +1034,19 @@ func TestContextRenderAttachment(t *testing.T) {
|
|||
assert.Equal(t, fmt.Sprintf("attachment; filename=\"%s\"", newFilename), w.Header().Get("Content-Disposition"))
|
||||
}
|
||||
|
||||
func TestContextRenderUTF8Attachment(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
newFilename := "new🧡_filename.go"
|
||||
|
||||
c.Request, _ = http.NewRequest("GET", "/", nil)
|
||||
c.FileAttachment("./gin.go", newFilename)
|
||||
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Contains(t, w.Body.String(), "func New() *Engine {")
|
||||
assert.Equal(t, `attachment; filename*=UTF-8''`+url.QueryEscape(newFilename), w.Header().Get("Content-Disposition"))
|
||||
}
|
||||
|
||||
// TestContextRenderYAML tests that the response is serialized as YAML
|
||||
// and Content-Type is set to application/x-yaml
|
||||
func TestContextRenderYAML(t *testing.T) {
|
||||
|
|
11
utils.go
11
utils.go
|
@ -12,6 +12,7 @@ import (
|
|||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// BindKey indicates a default bind key.
|
||||
|
@ -151,3 +152,13 @@ func resolveAddress(addr []string) string {
|
|||
panic("too many parameters")
|
||||
}
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/53069040/checking-a-string-contains-only-ascii-characters
|
||||
func isASCII(s string) bool {
|
||||
for i := 0; i < len(s); i++ {
|
||||
if s[i] > unicode.MaxASCII {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -143,3 +143,8 @@ func TestMarshalXMLforH(t *testing.T) {
|
|||
e := h.MarshalXML(enc, x)
|
||||
assert.Error(t, e)
|
||||
}
|
||||
|
||||
func TestIsASCII(t *testing.T) {
|
||||
assert.Equal(t, isASCII("test"), true)
|
||||
assert.Equal(t, isASCII("🧡💛💚💙💜"), false)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue