mirror of
https://github.com/golang/go
synced 2024-11-20 04:44:40 -07:00
mime/multipart: allow setting the Writer boundary
Fixes #4490 R=golang-dev, rsc CC=golang-dev https://golang.org/cl/6924044
This commit is contained in:
parent
9c9e811bb3
commit
575de93dd3
@ -30,11 +30,38 @@ func NewWriter(w io.Writer) *Writer {
|
||||
}
|
||||
}
|
||||
|
||||
// Boundary returns the Writer's randomly selected boundary string.
|
||||
// Boundary returns the Writer's boundary.
|
||||
func (w *Writer) Boundary() string {
|
||||
return w.boundary
|
||||
}
|
||||
|
||||
// SetBoundary overrides the Writer's default randomly-generated
|
||||
// boundary separator with an explicit value.
|
||||
//
|
||||
// SetBoundary must be called before any parts are created, may only
|
||||
// contain certain ASCII characters, and must be 1-69 bytes long.
|
||||
func (w *Writer) SetBoundary(boundary string) error {
|
||||
if w.lastpart != nil {
|
||||
return errors.New("mime: SetBoundary called after write")
|
||||
}
|
||||
// rfc2046#section-5.1.1
|
||||
if len(boundary) < 1 || len(boundary) > 69 {
|
||||
return errors.New("mime: invalid boundary length")
|
||||
}
|
||||
for _, b := range boundary {
|
||||
if 'A' <= b && b <= 'Z' || 'a' <= b && b <= 'z' || '0' <= b && b <= '9' {
|
||||
continue
|
||||
}
|
||||
switch b {
|
||||
case '\'', '(', ')', '+', '_', ',', '-', '.', '/', ':', '=', '?':
|
||||
continue
|
||||
}
|
||||
return errors.New("mime: invalid boundary character")
|
||||
}
|
||||
w.boundary = boundary
|
||||
return nil
|
||||
}
|
||||
|
||||
// FormDataContentType returns the Content-Type for an HTTP
|
||||
// multipart/form-data with this Writer's Boundary.
|
||||
func (w *Writer) FormDataContentType() string {
|
||||
|
@ -7,6 +7,7 @@ package multipart
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@ -76,3 +77,37 @@ func TestWriter(t *testing.T) {
|
||||
t.Fatalf("expected end of parts; got %v, %v", part, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriterSetBoundary(t *testing.T) {
|
||||
var b bytes.Buffer
|
||||
w := NewWriter(&b)
|
||||
tests := []struct {
|
||||
b string
|
||||
ok bool
|
||||
}{
|
||||
{"abc", true},
|
||||
{"", false},
|
||||
{"ungültig", false},
|
||||
{"!", false},
|
||||
{strings.Repeat("x", 69), true},
|
||||
{strings.Repeat("x", 70), false},
|
||||
{"bad!ascii!", false},
|
||||
{"my-separator", true},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
err := w.SetBoundary(tt.b)
|
||||
got := err == nil
|
||||
if got != tt.ok {
|
||||
t.Errorf("%d. boundary %q = %v (%v); want %v", i, tt.b, got, err, tt.ok)
|
||||
} else if tt.ok {
|
||||
got := w.Boundary()
|
||||
if got != tt.b {
|
||||
t.Errorf("boundary = %q; want %q", got, tt.b)
|
||||
}
|
||||
}
|
||||
}
|
||||
w.Close()
|
||||
if got := b.String(); !strings.Contains(got, "\r\n--my-separator--\r\n") {
|
||||
t.Errorf("expected my-separator in output. got: %q", got)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user