github.com/euank/go@v0.0.0-20160829210321-495514729181/src/mime/multipart/formdata_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" 10 "os" 11 "regexp" 12 "strings" 13 "testing" 14 ) 15 16 func TestReadForm(t *testing.T) { 17 testBody := regexp.MustCompile("\n").ReplaceAllString(message, "\r\n") 18 b := strings.NewReader(testBody) 19 r := NewReader(b, boundary) 20 f, err := r.ReadForm(25) 21 if err != nil { 22 t.Fatal("ReadForm:", err) 23 } 24 defer f.RemoveAll() 25 if g, e := f.Value["texta"][0], textaValue; g != e { 26 t.Errorf("texta value = %q, want %q", g, e) 27 } 28 if g, e := f.Value["textb"][0], textbValue; g != e { 29 t.Errorf("texta value = %q, want %q", g, e) 30 } 31 fd := testFile(t, f.File["filea"][0], "filea.txt", fileaContents) 32 if _, ok := fd.(*os.File); ok { 33 t.Error("file is *os.File, should not be") 34 } 35 fd.Close() 36 fd = testFile(t, f.File["fileb"][0], "fileb.txt", filebContents) 37 if _, ok := fd.(*os.File); !ok { 38 t.Errorf("file has unexpected underlying type %T", fd) 39 } 40 fd.Close() 41 } 42 43 func testFile(t *testing.T, fh *FileHeader, efn, econtent string) File { 44 if fh.Filename != efn { 45 t.Errorf("filename = %q, want %q", fh.Filename, efn) 46 } 47 f, err := fh.Open() 48 if err != nil { 49 t.Fatal("opening file:", err) 50 } 51 b := new(bytes.Buffer) 52 _, err = io.Copy(b, f) 53 if err != nil { 54 t.Fatal("copying contents:", err) 55 } 56 if g := b.String(); g != econtent { 57 t.Errorf("contents = %q, want %q", g, econtent) 58 } 59 return f 60 } 61 62 const ( 63 fileaContents = "This is a test file." 64 filebContents = "Another test file." 65 textaValue = "foo" 66 textbValue = "bar" 67 boundary = `MyBoundary` 68 ) 69 70 const message = ` 71 --MyBoundary 72 Content-Disposition: form-data; name="filea"; filename="filea.txt" 73 Content-Type: text/plain 74 75 ` + fileaContents + ` 76 --MyBoundary 77 Content-Disposition: form-data; name="fileb"; filename="fileb.txt" 78 Content-Type: text/plain 79 80 ` + filebContents + ` 81 --MyBoundary 82 Content-Disposition: form-data; name="texta" 83 84 ` + textaValue + ` 85 --MyBoundary 86 Content-Disposition: form-data; name="textb" 87 88 ` + textbValue + ` 89 --MyBoundary-- 90 ` 91 92 func TestReadForm_NoReadAfterEOF(t *testing.T) { 93 maxMemory := int64(32) << 20 94 boundary := `---------------------------8d345eef0d38dc9` 95 body := ` 96 -----------------------------8d345eef0d38dc9 97 Content-Disposition: form-data; name="version" 98 99 171 100 -----------------------------8d345eef0d38dc9--` 101 102 mr := NewReader(&failOnReadAfterErrorReader{t: t, r: strings.NewReader(body)}, boundary) 103 104 f, err := mr.ReadForm(maxMemory) 105 if err != nil { 106 t.Fatal(err) 107 } 108 t.Logf("Got: %#v", f) 109 } 110 111 // failOnReadAfterErrorReader is an io.Reader wrapping r. 112 // It fails t if any Read is called after a failing Read. 113 type failOnReadAfterErrorReader struct { 114 t *testing.T 115 r io.Reader 116 sawErr error 117 } 118 119 func (r *failOnReadAfterErrorReader) Read(p []byte) (n int, err error) { 120 if r.sawErr != nil { 121 r.t.Fatalf("unexpected Read on Reader after previous read saw error %v", r.sawErr) 122 } 123 n, err = r.r.Read(p) 124 r.sawErr = err 125 return 126 }