github.com/tidwall/go@v0.0.0-20170415222209-6694a6888b7d/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  	if fh.Size != int64(len(econtent)) {
    48  		t.Errorf("size = %d, want %d", fh.Size, len(econtent))
    49  	}
    50  	f, err := fh.Open()
    51  	if err != nil {
    52  		t.Fatal("opening file:", err)
    53  	}
    54  	b := new(bytes.Buffer)
    55  	_, err = io.Copy(b, f)
    56  	if err != nil {
    57  		t.Fatal("copying contents:", err)
    58  	}
    59  	if g := b.String(); g != econtent {
    60  		t.Errorf("contents = %q, want %q", g, econtent)
    61  	}
    62  	return f
    63  }
    64  
    65  const (
    66  	fileaContents = "This is a test file."
    67  	filebContents = "Another test file."
    68  	textaValue    = "foo"
    69  	textbValue    = "bar"
    70  	boundary      = `MyBoundary`
    71  )
    72  
    73  const message = `
    74  --MyBoundary
    75  Content-Disposition: form-data; name="filea"; filename="filea.txt"
    76  Content-Type: text/plain
    77  
    78  ` + fileaContents + `
    79  --MyBoundary
    80  Content-Disposition: form-data; name="fileb"; filename="fileb.txt"
    81  Content-Type: text/plain
    82  
    83  ` + filebContents + `
    84  --MyBoundary
    85  Content-Disposition: form-data; name="texta"
    86  
    87  ` + textaValue + `
    88  --MyBoundary
    89  Content-Disposition: form-data; name="textb"
    90  
    91  ` + textbValue + `
    92  --MyBoundary--
    93  `
    94  
    95  func TestReadForm_NoReadAfterEOF(t *testing.T) {
    96  	maxMemory := int64(32) << 20
    97  	boundary := `---------------------------8d345eef0d38dc9`
    98  	body := `
    99  -----------------------------8d345eef0d38dc9
   100  Content-Disposition: form-data; name="version"
   101  
   102  171
   103  -----------------------------8d345eef0d38dc9--`
   104  
   105  	mr := NewReader(&failOnReadAfterErrorReader{t: t, r: strings.NewReader(body)}, boundary)
   106  
   107  	f, err := mr.ReadForm(maxMemory)
   108  	if err != nil {
   109  		t.Fatal(err)
   110  	}
   111  	t.Logf("Got: %#v", f)
   112  }
   113  
   114  // failOnReadAfterErrorReader is an io.Reader wrapping r.
   115  // It fails t if any Read is called after a failing Read.
   116  type failOnReadAfterErrorReader struct {
   117  	t      *testing.T
   118  	r      io.Reader
   119  	sawErr error
   120  }
   121  
   122  func (r *failOnReadAfterErrorReader) Read(p []byte) (n int, err error) {
   123  	if r.sawErr != nil {
   124  		r.t.Fatalf("unexpected Read on Reader after previous read saw error %v", r.sawErr)
   125  	}
   126  	n, err = r.r.Read(p)
   127  	r.sawErr = err
   128  	return
   129  }