[go] net/http/httptrace: add hook for end of request life cycle

47 views
Skip to first unread message

Sina Siadat (Gerrit)

unread,
Aug 4, 2016, 5:22:14 PM8/4/16
to Brad Fitzpatrick, Ian Lance Taylor, golang-co...@googlegroups.com
Reviewers: Brad Fitzpatrick

Sina Siadat uploaded a change:
https://go-review.googlesource.com/25510

net/http/httptrace: add hook for end of request life cycle

RequestCompleted is called at the end of the request life cycle. The
provided error indicates whether the request completed successfully.

Updates #16400.

Change-Id: I2eb178ddf193e42de2b27ef5a7f17070fef61fc2
---
M src/net/http/client.go
M src/net/http/httptrace/trace.go
M src/net/http/transport_test.go
3 files changed, 44 insertions(+), 9 deletions(-)



diff --git a/src/net/http/client.go b/src/net/http/client.go
index 993c247..edd54a8 100644
--- a/src/net/http/client.go
+++ b/src/net/http/client.go
@@ -17,6 +17,7 @@
"io"
"io/ioutil"
"log"
+ "net/http/httptrace"
"net/url"
"strings"
"sync"
@@ -178,15 +179,23 @@
// the returned Response.Body is already closed.
//
// Generally Get, Post, or PostForm will be used instead of Do.
-func (c *Client) Do(req *Request) (*Response, error) {
+func (c *Client) Do(req *Request) (resp *Response, err error) {
+ defer func() {
+ if trace := httptrace.ContextClientTrace(req.Context()); trace != nil &&
trace.RequestCompleted != nil {
+ trace.RequestCompleted(err)
+ }
+ }()
method := valueOrDefault(req.Method, "GET")
if method == "GET" || method == "HEAD" {
- return c.doFollowingRedirects(req, shouldRedirectGet)
+ resp, err = c.doFollowingRedirects(req, shouldRedirectGet)
+ return resp, err
}
if method == "POST" || method == "PUT" {
- return c.doFollowingRedirects(req, shouldRedirectPost)
+ resp, err = c.doFollowingRedirects(req, shouldRedirectPost)
+ return resp, err
}
- return c.send(req, c.deadline())
+ resp, err = c.send(req, c.deadline())
+ return resp, err
}

func (c *Client) deadline() time.Time {
@@ -412,10 +421,16 @@
// To make a request with custom headers, use NewRequest and Client.Do.
func (c *Client) Get(url string) (resp *Response, err error) {
req, err := NewRequest("GET", url, nil)
+ defer func() {
+ if trace := httptrace.ContextClientTrace(req.Context()); trace != nil &&
trace.RequestCompleted != nil {
+ trace.RequestCompleted(err)
+ }
+ }()
if err != nil {
return nil, err
}
- return c.doFollowingRedirects(req, shouldRedirectGet)
+ resp, err = c.doFollowingRedirects(req, shouldRedirectGet)
+ return resp, err
}

func alwaysFalse() bool { return false }
@@ -572,11 +587,17 @@
// To set custom headers, use NewRequest and Client.Do.
func (c *Client) Post(url string, bodyType string, body io.Reader) (resp
*Response, err error) {
req, err := NewRequest("POST", url, body)
+ defer func() {
+ if trace := httptrace.ContextClientTrace(req.Context()); trace != nil &&
trace.RequestCompleted != nil {
+ trace.RequestCompleted(err)
+ }
+ }()
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", bodyType)
- return c.doFollowingRedirects(req, shouldRedirectPost)
+ resp, err = c.doFollowingRedirects(req, shouldRedirectPost)
+ return resp, err
}

// PostForm issues a POST to the specified URL, with data's keys and
@@ -629,10 +650,19 @@
// 307 (Temporary Redirect)
func (c *Client) Head(url string) (resp *Response, err error) {
req, err := NewRequest("HEAD", url, nil)
+ defer func() {
+ if trace := httptrace.ContextClientTrace(req.Context()); trace != nil &&
trace.RequestCompleted != nil {
+ trace.RequestCompleted(err)
+ }
+ }()
if err != nil {
+ if trace := httptrace.ContextClientTrace(req.Context()); trace != nil &&
trace.RequestCompleted != nil {
+ trace.RequestCompleted(err)
+ }
return nil, err
}
- return c.doFollowingRedirects(req, shouldRedirectGet)
+ resp, err = c.doFollowingRedirects(req, shouldRedirectGet)
+ return resp, err
}

// cancelTimerBody is an io.ReadCloser that wraps rc with two features:
diff --git a/src/net/http/httptrace/trace.go
b/src/net/http/httptrace/trace.go
index 6f187a7..8320043 100644
--- a/src/net/http/httptrace/trace.go
+++ b/src/net/http/httptrace/trace.go
@@ -101,6 +101,9 @@
// Continue" response.
Got100Continue func()

+ // RequestCompleted is called at the end of the request life cycle.
+ RequestCompleted func(error)
+
// DNSStart is called when a DNS lookup begins.
DNSStart func(DNSStartInfo)

diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
index 749d453..2eddc79 100644
--- a/src/net/http/transport_test.go
+++ b/src/net/http/transport_test.go
@@ -3287,8 +3287,9 @@
}
logf("ConnectDone: connected to %s %s = %v", network, addr, err)
},
- Wait100Continue: func() { logf("Wait100Continue") },
- Got100Continue: func() { logf("Got100Continue") },
+ Wait100Continue: func() { logf("Wait100Continue") },
+ Got100Continue: func() { logf("Got100Continue") },
+ RequestCompleted: func(err error) { logf("RequestCompleted = %v", err) },
WroteRequest: func(e httptrace.WroteRequestInfo) {
close(gotWroteReqEvent)
logf("WroteRequest: %+v", e)
@@ -3347,6 +3348,7 @@
}
wantOnce("Wait100Continue")
wantOnce("Got100Continue")
+ wantOnce("RequestCompleted = <nil>")
wantOnce("WroteRequest: {Err:<nil>}")
if strings.Contains(got, " to udp ") {
t.Errorf("should not see UDP (DNS) connections")

--
https://go-review.googlesource.com/25510
Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>

Brad Fitzpatrick (Gerrit)

unread,
Aug 4, 2016, 5:33:40 PM8/4/16
to Sina Siadat, Brad Fitzpatrick, golang-co...@googlegroups.com
Brad Fitzpatrick has posted comments on this change.

net/http/httptrace: add hook for end of request life cycle

Patch Set 1:

R=go1.8

--
https://go-review.googlesource.com/25510
Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
Gerrit-HasComments: No

Sina Siadat (Gerrit)

unread,
Aug 5, 2016, 3:49:09 AM8/5/16
to Brad Fitzpatrick, golang-co...@googlegroups.com
Reviewers: Brad Fitzpatrick

Sina Siadat uploaded a new patch set:
https://go-review.googlesource.com/25510

net/http/httptrace: add hook for end of request life cycle

RequestCompleted is called at the end of the request life cycle. The
provided overall error indicates whether the request completed
successfully.

Updates #16400

Change-Id: I2eb178ddf193e42de2b27ef5a7f17070fef61fc2
---
M src/net/http/client.go
M src/net/http/httptrace/trace.go
M src/net/http/transport_test.go
3 files changed, 45 insertions(+), 9 deletions(-)

Sina Siadat (Gerrit)

unread,
Aug 5, 2016, 4:03:09 AM8/5/16
to Brad Fitzpatrick, golang-co...@googlegroups.com
Reviewers: Brad Fitzpatrick

Sina Siadat uploaded a new patch set:
https://go-review.googlesource.com/25510

net/http/httptrace: call new hook when request completes

RequestCompleted is called at the end of the request life cycle. The
provided overall error indicates whether the request completed
successfully.

Updates #16400

Change-Id: I2eb178ddf193e42de2b27ef5a7f17070fef61fc2
---
M src/net/http/client.go
M src/net/http/httptrace/trace.go
M src/net/http/transport_test.go
3 files changed, 45 insertions(+), 9 deletions(-)

Brad Fitzpatrick (Gerrit)

unread,
Sep 30, 2016, 12:38:14 PM9/30/16
to Sina Siadat, Brad Fitzpatrick, golang-co...@googlegroups.com
Brad Fitzpatrick has abandoned this change. (
https://go-review.googlesource.com/25510 )

Change subject: net/http/httptrace: call new hook when request completes
......................................................................


Abandoned

The bug has been closed, so this is no longer applicable. See discussion
there. We can reopen this when needed.
Reply all
Reply to author
Forward
0 new messages