From 3546c31c2b0781daf233fa22a9fb2b8fd1cb2cbe Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Tue, 1 Mar 2016 01:13:50 +0200 Subject: [PATCH] Issue #60: skip body copying in DoTimeout. This should improve DoTimeout performance when dealing with big request and/or response bodies --- client.go | 6 ++++-- http.go | 22 ++++++++++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/client.go b/client.go index 1745e13..b48e9fa 100644 --- a/client.go +++ b/client.go @@ -862,7 +862,8 @@ func clientDoDeadlineFreeConn(req *Request, resp *Response, deadline time.Time, // Make req and resp copies, since on timeout they no longer // may be accessed. reqCopy := AcquireRequest() - req.CopyTo(reqCopy) + req.copyToSkipBody(reqCopy) + swapRequestBody(req, reqCopy) respCopy := AcquireResponse() // Note that the request continues execution on ErrTimeout until @@ -889,7 +890,8 @@ func clientDoDeadlineFreeConn(req *Request, resp *Response, deadline time.Time, var err error select { case err = <-ch: - respCopy.CopyTo(resp) + respCopy.copyToSkipBody(resp) + swapResponseBody(resp, respCopy) ReleaseResponse(respCopy) ReleaseRequest(reqCopy) errorChPool.Put(chv) diff --git a/http.go b/http.go index b2ec26d..5fc4b62 100644 --- a/http.go +++ b/http.go @@ -433,9 +433,13 @@ func (req *Request) ResetBody() { // CopyTo copies req contents to dst except of body stream. func (req *Request) CopyTo(dst *Request) { + req.copyToSkipBody(dst) + dst.body = append(dst.body[:0], req.body...) +} + +func (req *Request) copyToSkipBody(dst *Request) { dst.Reset() req.Header.CopyTo(&dst.Header) - dst.body = append(dst.body[:0], req.body...) req.uri.CopyTo(&dst.uri) dst.parsedURI = req.parsedURI @@ -449,12 +453,26 @@ func (req *Request) CopyTo(dst *Request) { // CopyTo copies resp contents to dst except of body stream. func (resp *Response) CopyTo(dst *Response) { + resp.copyToSkipBody(dst) + dst.body = append(dst.body[:0], resp.body...) +} + +func (resp *Response) copyToSkipBody(dst *Response) { dst.Reset() resp.Header.CopyTo(&dst.Header) - dst.body = append(dst.body[:0], resp.body...) dst.SkipBody = resp.SkipBody } +func swapRequestBody(a, b *Request) { + a.body, b.body = b.body, a.body + a.bodyStream, b.bodyStream = b.bodyStream, a.bodyStream +} + +func swapResponseBody(a, b *Response) { + a.body, b.body = b.body, a.body + a.bodyStream, b.bodyStream = b.bodyStream, a.bodyStream +} + // URI returns request URI func (req *Request) URI() *URI { req.parseURI()