/* Keep Alive Client*/
HttpClient{
Client: &http.Client{
Transport: &http.Transport{
Dial: (&net.Dialer{
Timeout: dialTimeout,
KeepAlive: dialTimeout * 60,
}).Dial,
DisableKeepAlives: false,
MaxIdleConnsPerHost: idleConnectionsPerHost,
},
},
Timeout: 5 * time.Second,
}
/* Execute Request */
timeoutContext, cancelFunction := context.WithTimeout(context.Background(), self.Timeout)
defer cancelFunction()
if response, err = self.Client.Do(request.WithContext(timeoutContext)); err == nil {
defer response.Body.Close()
/* Check If Request was Successful */
statusCode = response.StatusCode
if response.StatusCode == http.StatusOK {
/* Read Body & Decode if Response came & unmarshal entity is supplied */
if responseBytes, err = ioutil.ReadAll(response.Body); err == nil && unmarshalledResponse != nil {
//Process Response
}
} else {
err = errors.New(fmt.Sprintf("Non 200 Response. Status Code: %v", response.StatusCode))
}
}
In Golang whenever a request times out in a Keep-Alive connection that connection is lost and is Reset. For the above code incase of timeout Seeing Packets in Wireshark reveals that RST is sent by the client hence connection is no longer reused.
Event tried using Timeout of Httpclient rather than ContextWithTimeout but having similar findings where connection gets reset.
Anyway we can retain established keep-alive connection even in case of a Timeout of request.