Skip to content

Commit 58d38b1

Browse files
committed
reader: properly implement io.Reader
The io.Reader interface specifies that once we reach an EOF indicator, the next read from the stream should return 0, io.EOF. However, our reader didn't work that way, causing us to attempt to read the next packet from the underlying reader. In some cases, such a packet won't exist until we've responded to the one we already got, causing us to hang. This was fixed in git-lfs/git-lfs#3902, but never ported over to here. Let's port that change over here, and add a Reset method to allow users to continue with the next packet if there's more data to read from the underlying stream.
1 parent e90ca55 commit 58d38b1

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

reader.go

+13
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ type PktlineReader struct {
88
pl *Pktline
99

1010
buf []byte
11+
12+
eof bool
1113
}
1214

1315
// NewPktlineReader returns a new *PktlineReader, which will read from the
@@ -39,6 +41,10 @@ func NewPktlineReaderFromPktline(pl *Pktline, c int) *PktlineReader {
3941
func (r *PktlineReader) Read(p []byte) (int, error) {
4042
var n int
4143

44+
if r.eof {
45+
return 0, io.EOF
46+
}
47+
4248
if len(r.buf) > 0 {
4349
// If there is data in the buffer, shift as much out of it and
4450
// into the given "p" as we can.
@@ -62,6 +68,7 @@ func (r *PktlineReader) Read(p []byte) (int, error) {
6268
// reached the end of processing for this particular
6369
// packet, so let's terminate.
6470

71+
r.eof = true
6572
return n, io.EOF
6673
}
6774

@@ -79,3 +86,9 @@ func (r *PktlineReader) Read(p []byte) (int, error) {
7986

8087
return n, nil
8188
}
89+
90+
// Reset causes the reader to reset the end-of-file indicator and continue
91+
// reading packets from the underlying reader.
92+
func (r *PktlineReader) Reset() {
93+
r.eof = false
94+
}

reader_test.go

+31
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,34 @@ func TestPktlineReaderReadsManyPacketsInMultipleCallsWithEvenBuffering(t *testin
141141
assert.Equal(t, 0, n3)
142142
assert.Equal(t, io.EOF, e3)
143143
}
144+
145+
func TestPktlineReaderReadEOFAfterEOF(t *testing.T) {
146+
var buf bytes.Buffer
147+
148+
writePacket(t, &buf, []byte("asdf"))
149+
writePacket(t, &buf, []byte("abcd"))
150+
151+
pr := NewPktlineReader(&buf, 10)
152+
153+
var p1 [5]byte
154+
155+
n, err := pr.Read(p1[:])
156+
assert.Equal(t, err, io.EOF)
157+
assert.Equal(t, 4, n)
158+
assert.Equal(t, []byte("asdf"), p1[0:n])
159+
160+
n, err = pr.Read(p1[:])
161+
assert.Equal(t, err, io.EOF)
162+
assert.Equal(t, 0, n)
163+
164+
pr.Reset()
165+
166+
n, err = pr.Read(p1[:])
167+
assert.Equal(t, err, io.EOF)
168+
assert.Equal(t, 4, n)
169+
assert.Equal(t, []byte("abcd"), p1[0:n])
170+
171+
n, err = pr.Read(p1[:])
172+
assert.Equal(t, err, io.EOF)
173+
assert.Equal(t, 0, n)
174+
}

0 commit comments

Comments
 (0)