github.com/kdevb0x/go@v0.0.0-20180115030120-39687051e9e7/src/mime/multipart/writer_test.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package multipart 6 7 import ( 8 "bytes" 9 "io/ioutil" 10 "net/textproto" 11 "strings" 12 "testing" 13 ) 14 15 func TestWriter(t *testing.T) { 16 fileContents := []byte("my file contents") 17 18 var b bytes.Buffer 19 w := NewWriter(&b) 20 { 21 part, err := w.CreateFormFile("myfile", "my-file.txt") 22 if err != nil { 23 t.Fatalf("CreateFormFile: %v", err) 24 } 25 part.Write(fileContents) 26 err = w.WriteField("key", "val") 27 if err != nil { 28 t.Fatalf("WriteField: %v", err) 29 } 30 part.Write([]byte("val")) 31 err = w.Close() 32 if err != nil { 33 t.Fatalf("Close: %v", err) 34 } 35 s := b.String() 36 if len(s) == 0 { 37 t.Fatal("String: unexpected empty result") 38 } 39 if s[0] == '\r' || s[0] == '\n' { 40 t.Fatal("String: unexpected newline") 41 } 42 } 43 44 r := NewReader(&b, w.Boundary()) 45 46 part, err := r.NextPart() 47 if err != nil { 48 t.Fatalf("part 1: %v", err) 49 } 50 if g, e := part.FormName(), "myfile"; g != e { 51 t.Errorf("part 1: want form name %q, got %q", e, g) 52 } 53 slurp, err := ioutil.ReadAll(part) 54 if err != nil { 55 t.Fatalf("part 1: ReadAll: %v", err) 56 } 57 if e, g := string(fileContents), string(slurp); e != g { 58 t.Errorf("part 1: want contents %q, got %q", e, g) 59 } 60 61 part, err = r.NextPart() 62 if err != nil { 63 t.Fatalf("part 2: %v", err) 64 } 65 if g, e := part.FormName(), "key"; g != e { 66 t.Errorf("part 2: want form name %q, got %q", e, g) 67 } 68 slurp, err = ioutil.ReadAll(part) 69 if err != nil { 70 t.Fatalf("part 2: ReadAll: %v", err) 71 } 72 if e, g := "val", string(slurp); e != g { 73 t.Errorf("part 2: want contents %q, got %q", e, g) 74 } 75 76 part, err = r.NextPart() 77 if part != nil || err == nil { 78 t.Fatalf("expected end of parts; got %v, %v", part, err) 79 } 80 } 81 82 func TestWriterSetBoundary(t *testing.T) { 83 tests := []struct { 84 b string 85 ok bool 86 }{ 87 {"abc", true}, 88 {"", false}, 89 {"ungültig", false}, 90 {"!", false}, 91 {strings.Repeat("x", 70), true}, 92 {strings.Repeat("x", 71), false}, 93 {"bad!ascii!", false}, 94 {"my-separator", true}, 95 {"with space", true}, 96 {"badspace ", false}, 97 } 98 for i, tt := range tests { 99 var b bytes.Buffer 100 w := NewWriter(&b) 101 err := w.SetBoundary(tt.b) 102 got := err == nil 103 if got != tt.ok { 104 t.Errorf("%d. boundary %q = %v (%v); want %v", i, tt.b, got, err, tt.ok) 105 } else if tt.ok { 106 got := w.Boundary() 107 if got != tt.b { 108 t.Errorf("boundary = %q; want %q", got, tt.b) 109 } 110 w.Close() 111 wantSub := "\r\n--" + tt.b + "--\r\n" 112 if got := b.String(); !strings.Contains(got, wantSub) { 113 t.Errorf("expected %q in output. got: %q", wantSub, got) 114 } 115 } 116 } 117 } 118 119 func TestWriterBoundaryGoroutines(t *testing.T) { 120 // Verify there's no data race accessing any lazy boundary if it's used by 121 // different goroutines. This was previously broken by 122 // https://codereview.appspot.com/95760043/ and reverted in 123 // https://codereview.appspot.com/117600043/ 124 w := NewWriter(ioutil.Discard) 125 done := make(chan int) 126 go func() { 127 w.CreateFormField("foo") 128 done <- 1 129 }() 130 w.Boundary() 131 <-done 132 } 133 134 func TestSortedHeader(t *testing.T) { 135 var buf bytes.Buffer 136 w := NewWriter(&buf) 137 if err := w.SetBoundary("MIMEBOUNDARY"); err != nil { 138 t.Fatalf("Error setting mime boundary: %v", err) 139 } 140 141 header := textproto.MIMEHeader{ 142 "A": {"2"}, 143 "B": {"5", "7", "6"}, 144 "C": {"4"}, 145 "M": {"3"}, 146 "Z": {"1"}, 147 } 148 149 part, err := w.CreatePart(header) 150 if err != nil { 151 t.Fatalf("Unable to create part: %v", err) 152 } 153 part.Write([]byte("foo")) 154 155 w.Close() 156 157 want := "--MIMEBOUNDARY\r\nA: 2\r\nB: 5\r\nB: 7\r\nB: 6\r\nC: 4\r\nM: 3\r\nZ: 1\r\n\r\nfoo\r\n--MIMEBOUNDARY--\r\n" 158 if want != buf.String() { 159 t.Fatalf("\n got: %q\nwant: %q\n", buf.String(), want) 160 } 161 }