Read N bytes from a TLS stream and block the caller while still respecting the deadline

95 views
Skip to first unread message

LastName Almaember

unread,
Nov 30, 2021, 5:20:54 PM11/30/21
to golang-nuts
Hello,

I have this function:
// Read a message from a stream
func ReadFromStream(rd io.Reader) (Message, error) {
result := Message{}
// read the first nine bytes only
// (mtype + length)
buf := make([]byte, 9)
read, err := rd.Read(buf)
if err != nil {
return result, err
}
if read < 9 {
// we didn't read a full header. Well, shit.
return result, InputTooShort
}

result.MType = buf[0]
contentLen := binary.LittleEndian.Uint64(buf[1:])
result.Content = make([]byte, contentLen)

read, err = rd.Read(result.Content)
if err != nil {
return result, err
}
if read < int(contentLen) {
return result, InputTooShort
}
return result, nil
}

It's meant to first read a nine-byte header (8 bits of a type field followed by a 64 bit length).
In theory, it should work fine, but it always immediately returns InputTooShort
(right at the first check).

A bufio might work for this, however, I'm not confident that it will respect the
deadline set on the connection.

Thanks for the attention,
almaember

P.S. This is my system:
[almaember@manjarocado ~]$ uname -a
Linux manjarocado 5.13.19-2-MANJARO #1 SMP PREEMPT Sun Sep 19 21:31:53 UTC 2021 x86_64 GNU/Linux
[almaember@manjarocado ~]$ go version
go version go1.17.3 linux/amd64

wagner riffel

unread,
Dec 1, 2021, 2:23:12 AM12/1/21
to LastName Almaember, golang-nuts
On Tue Nov 30, 2021 at 11:20 PM CET, LastName Almaember wrote:
> It's meant to first read a nine-byte header (8 bits of a type field
> followed by a 64 bit length). In theory, it should work fine, but it
> always immediately returns InputTooShort (right at the first check).

io.Readers returns up to len(p), not exactly len(p), you have to loop
over calling read until you have enough input, there's io.ReadAtLeast
and io.ReadFull helpers that does that for you.

> A bufio *might* work for this, however, I'm not confident that it will
> respect the deadline set on the connection.
>

bufio will respect your deadline, it doesn't skip errors from the
underlying reader, just returns them up. I suspect that it doesn't solve
the issue mentioned above tho.

BR.
-w
Reply all
Reply to author
Forward
0 new messages