mirror of https://github.com/golang/go.git
mime/multipart: add helper to build content-disposition header contents
This PR adds an helper FileContentDisposition that builds multipart
Content-Disposition header contents with field name and file name,
escaping quotes and escape characters.
The function is then called in the related helper CreateFormFile.
The new function allows users to add other custom MIMEHeaders,
without having to rewrite the char escaping logic of field name and
file name, which is provided by the new helper.
Fixes #46771
Change-Id: Ifc82a79583feb6dd609ca1e6024e612fb58c05ce
GitHub-Last-Rev: 969f846fa9
GitHub-Pull-Request: golang/go#63324
Reviewed-on: https://go-review.googlesource.com/c/go/+/531995
Reviewed-by: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
This commit is contained in:
parent
a68bf75d34
commit
d729053edf
|
|
@ -0,0 +1 @@
|
|||
pkg mime/multipart, func FileContentDisposition(string, string) string #46771
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
The new helper function [FieldContentDisposition] builds multipart
|
||||
Content-Disposition header fields.
|
||||
|
|
@ -135,9 +135,7 @@ func escapeQuotes(s string) string {
|
|||
// a new form-data header with the provided field name and file name.
|
||||
func (w *Writer) CreateFormFile(fieldname, filename string) (io.Writer, error) {
|
||||
h := make(textproto.MIMEHeader)
|
||||
h.Set("Content-Disposition",
|
||||
fmt.Sprintf(`form-data; name="%s"; filename="%s"`,
|
||||
escapeQuotes(fieldname), escapeQuotes(filename)))
|
||||
h.Set("Content-Disposition", FileContentDisposition(fieldname, filename))
|
||||
h.Set("Content-Type", "application/octet-stream")
|
||||
return w.CreatePart(h)
|
||||
}
|
||||
|
|
@ -151,6 +149,13 @@ func (w *Writer) CreateFormField(fieldname string) (io.Writer, error) {
|
|||
return w.CreatePart(h)
|
||||
}
|
||||
|
||||
// FileContentDisposition returns the value of a Content-Disposition header
|
||||
// with the provided field name and file name.
|
||||
func FileContentDisposition(fieldname, filename string) string {
|
||||
return fmt.Sprintf(`form-data; name="%s"; filename="%s"`,
|
||||
escapeQuotes(fieldname), escapeQuotes(filename))
|
||||
}
|
||||
|
||||
// WriteField calls [Writer.CreateFormField] and then writes the given value.
|
||||
func (w *Writer) WriteField(fieldname, value string) error {
|
||||
p, err := w.CreateFormField(fieldname)
|
||||
|
|
|
|||
|
|
@ -172,3 +172,22 @@ func TestSortedHeader(t *testing.T) {
|
|||
t.Fatalf("\n got: %q\nwant: %q\n", buf.String(), want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileContentDisposition(t *testing.T) {
|
||||
tests := []struct {
|
||||
fieldname string
|
||||
filename string
|
||||
want string
|
||||
}{
|
||||
{"somefield", "somefile.txt", `form-data; name="somefield"; filename="somefile.txt"`},
|
||||
{`field"withquotes"`, "somefile.txt", `form-data; name="field\"withquotes\""; filename="somefile.txt"`},
|
||||
{`somefield`, `somefile"withquotes".txt`, `form-data; name="somefield"; filename="somefile\"withquotes\".txt"`},
|
||||
{`somefield\withbackslash`, "somefile.txt", `form-data; name="somefield\\withbackslash"; filename="somefile.txt"`},
|
||||
{"somefield", `somefile\withbackslash.txt`, `form-data; name="somefield"; filename="somefile\\withbackslash.txt"`},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
if found := FileContentDisposition(tt.fieldname, tt.filename); found != tt.want {
|
||||
t.Errorf(`%d. found: "%s"; want: "%s"`, i, found, tt.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue