How to set timeout for io.Reader?

I have code:

func ReadBodyWithTimeout(resp *http.Response) (data []byte, err error) {
	if resp == nil {
		return nil, errors.New("resp is nil.")
	}
	ch := make(chan bool, 0)
	buf := make([]byte, bytes.MinRead)
	var t int
	timer := time.NewTimer(time.Second * time.Duration(300))
	go func() {
		t, err = resp.Body.Read(buf)
		data = buf[:t]
		ch <- true
	}()
	select {
	case <-ch:
	case <-timer.C:
		err = errors.New("readbody timeout.")
	}
	timer.Stop()
	return
}

Use:

for {
	data, err := ReadBodyWithTimeout(resp)
	if err != nil || err == io.EOF {
		//TODO
	} else {
		break
	}
}

It can work properly, but because of the frequent creation of the timer, so there will be the risk of memory leaks, is there any way to solve this problem?
(PS: because some servers do not send data nor take the initiative to disconnect, in this case will lead to never jump out of the loop, so there is a need to set the timeout.

I have found a solution:

func init() {
	go func() {
		for {
			time.Sleep(time.Minute * 2)
			debug.FreeOSMemory()
		}
	}()
}

The HTTP client has timeout fields that you can use. The various network connection types also have SetDeadline methods for the purpose.

Maybe the article “Don’t use Go’s default HTTP client (in production)” is interesting in this context.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.