]> Cypherpunks repositories - gostls13.git/commitdiff
mime/multipart: allow setting the Writer boundary
authorBrad Fitzpatrick <bradfitz@golang.org>
Mon, 10 Dec 2012 21:30:42 +0000 (16:30 -0500)
committerBrad Fitzpatrick <bradfitz@golang.org>
Mon, 10 Dec 2012 21:30:42 +0000 (16:30 -0500)
Fixes #4490

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6924044

src/pkg/mime/multipart/writer.go
src/pkg/mime/multipart/writer_test.go

index ec70be492f5c5f6bc8a0a597457af1a5862183d3..e13a956afeed0c12a6029520d663eab50f549cf5 100644 (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 {
index 494e936c4c6de686360378fd7772906d0ff78d46..52d68bcb68c580415affd3d59c1906d80330985a 100644 (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)
+       }
+}