1
0
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:
Brad Fitzpatrick 2012-12-10 16:30:42 -05:00
parent 9c9e811bb3
commit 575de93dd3
2 changed files with 63 additions and 1 deletions

View File

@ -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 {

View File

@ -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)
}
}