mirror of
https://github.com/golang/go
synced 2024-11-11 19:41:36 -07:00
mime/multipart: test for overreading on a stream
Some multipart data arrives in a stream, where subsequent parts may not be ready yet. Read should return a complete part as soon as possible. Fixes #15431 Change-Id: Ie8c041b853f3e07f0f2a66fbf4bcab5fe9132a7c Reviewed-on: https://go-review.googlesource.com/32032 Run-TryBot: Quentin Smith <quentin@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
44febb28b6
commit
9e4a70e8fd
@ -324,6 +324,73 @@ func (s *slowReader) Read(p []byte) (int, error) {
|
||||
return s.r.Read(p[:1])
|
||||
}
|
||||
|
||||
type sentinelReader struct {
|
||||
// done is closed when this reader is read from.
|
||||
done chan struct{}
|
||||
}
|
||||
|
||||
func (s *sentinelReader) Read([]byte) (int, error) {
|
||||
if s.done != nil {
|
||||
close(s.done)
|
||||
s.done = nil
|
||||
}
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
||||
// TestMultipartStreamReadahead tests that PartReader does not block
|
||||
// on reading past the end of a part, ensuring that it can be used on
|
||||
// a stream like multipart/x-mixed-replace. See golang.org/issue/15431
|
||||
func TestMultipartStreamReadahead(t *testing.T) {
|
||||
testBody1 := `
|
||||
This is a multi-part message. This line is ignored.
|
||||
--MyBoundary
|
||||
foo-bar: baz
|
||||
|
||||
Body
|
||||
--MyBoundary
|
||||
`
|
||||
testBody2 := `foo-bar: bop
|
||||
|
||||
Body 2
|
||||
--MyBoundary--
|
||||
`
|
||||
done1 := make(chan struct{})
|
||||
reader := NewReader(
|
||||
io.MultiReader(
|
||||
strings.NewReader(testBody1),
|
||||
&sentinelReader{done1},
|
||||
strings.NewReader(testBody2)),
|
||||
"MyBoundary")
|
||||
|
||||
var i int
|
||||
readPart := func(hdr textproto.MIMEHeader, body string) {
|
||||
part, err := reader.NextPart()
|
||||
if part == nil || err != nil {
|
||||
t.Fatalf("Part %d: NextPart failed: %v", i, err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(part.Header, hdr) {
|
||||
t.Errorf("Part %d: part.Header = %v, want %v", i, part.Header, hdr)
|
||||
}
|
||||
data, err := ioutil.ReadAll(part)
|
||||
expectEq(t, body, string(data), fmt.Sprintf("Part %d body", i))
|
||||
if err != nil {
|
||||
t.Fatalf("Part %d: ReadAll failed: %v", i, err)
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
||||
readPart(textproto.MIMEHeader{"Foo-Bar": {"baz"}}, "Body")
|
||||
|
||||
select {
|
||||
case <-done1:
|
||||
t.Errorf("Reader read past second boundary")
|
||||
default:
|
||||
}
|
||||
|
||||
readPart(textproto.MIMEHeader{"Foo-Bar": {"bop"}}, "Body 2")
|
||||
}
|
||||
|
||||
func TestLineContinuation(t *testing.T) {
|
||||
// This body, extracted from an email, contains headers that span multiple
|
||||
// lines.
|
||||
|
Loading…
Reference in New Issue
Block a user