[go] net/http/httputil: don't panic in ReverseProxy unless running under a Server

1,016 views
Skip to first unread message

Brad Fitzpatrick (Gerrit)

unread,
Jul 9, 2018, 6:31:37 PM7/9/18
to Ian Lance Taylor, Andrew Bonventre, goph...@pubsubhelper.golang.org, Brad Fitzpatrick, golang-co...@googlegroups.com

Brad Fitzpatrick would like Ian Lance Taylor and Andrew Bonventre to review this change.

View Change

net/http/httputil: don't panic in ReverseProxy unless running under a Server

Prior to the fix to #23643, the ReverseProxy didn't panic with
ErrAbortHandler when the copy to a client failed.

During Go 1.11 beta testing, we found plenty of code using
ReverseProxy in tests that were unprepared for a panic.

Change the behavior to only panic when running under the http.Server
that'll handle the panic.

Updates #23643

Change-Id: Ic1fa8405fd54c858ce8c797cec79d006833a9f7d
---
M src/net/http/httputil/reverseproxy.go
M src/net/http/httputil/reverseproxy_test.go
2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go
index 2eda6b7..79dfa32 100644
--- a/src/net/http/httputil/reverseproxy.go
+++ b/src/net/http/httputil/reverseproxy.go
@@ -253,7 +253,11 @@
defer res.Body.Close()
// Since we're streaming the response, if we run into an error all we can do
// is abort the request. Issue 23643: ReverseProxy should use ErrAbortHandler
- // on read error while copying body
+ // on read error while copying body.
+ if !shouldPanicOnCopyError(req) {
+ log.Printf("suppressing panic for copyResponse error in test; copy error: %v", err)
+ return
+ }
panic(http.ErrAbortHandler)
}
res.Body.Close() // close now, instead of defer, to populate res.Trailer
@@ -271,6 +275,29 @@
}
}

+var inOurTests bool // whether we're in our own tests
+
+// shouldPanicOnCopyError reports whether the reverse proxy should
+// panic with http.ErrAbortHandler. This is the right thing to do by
+// default, but Go 1.10 and earlier did not, so existing unit tests
+// weren't expecting panics. Only panic in our own tests, or when
+// running under the HTTP server.
+// under an HTTP server.
+func shouldPanicOnCopyError(req *http.Request) bool {
+ if inOurTests {
+ // Our tests know to handle this panic.
+ return true
+ }
+ if req.Context().Value(http.ServerContextKey) != nil {
+ // We seem to be running under an HTTP server, so
+ // it'll recover the panic.
+ return true
+ }
+ // Otherwise act like Go 1.10 and earlier to not break
+ // existing tests.
+ return false
+}
+
// removeConnectionHeaders removes hop-by-hop headers listed in the "Connection" header of h.
// See RFC 7230, section 6.1
func removeConnectionHeaders(h http.Header) {
diff --git a/src/net/http/httputil/reverseproxy_test.go b/src/net/http/httputil/reverseproxy_test.go
index 0240bfa..2a12e75 100644
--- a/src/net/http/httputil/reverseproxy_test.go
+++ b/src/net/http/httputil/reverseproxy_test.go
@@ -29,6 +29,7 @@
const fakeHopHeader = "X-Fake-Hop-Header-For-Test"

func init() {
+ inOurTests = true
hopHeaders = append(hopHeaders, fakeHopHeader)
}


To view, visit change 122819. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: Ic1fa8405fd54c858ce8c797cec79d006833a9f7d
Gerrit-Change-Number: 122819
Gerrit-PatchSet: 1
Gerrit-Owner: Brad Fitzpatrick <brad...@golang.org>
Gerrit-Reviewer: Andrew Bonventre <andy...@golang.org>
Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
Gerrit-MessageType: newchange

Ian Lance Taylor (Gerrit)

unread,
Jul 9, 2018, 6:33:41 PM7/9/18
to Brad Fitzpatrick, goph...@pubsubhelper.golang.org, Andrew Bonventre, golang-co...@googlegroups.com

Patch set 1:Code-Review +2

View Change

1 comment:

To view, visit change 122819. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: Ic1fa8405fd54c858ce8c797cec79d006833a9f7d
Gerrit-Change-Number: 122819
Gerrit-PatchSet: 1
Gerrit-Owner: Brad Fitzpatrick <brad...@golang.org>
Gerrit-Reviewer: Andrew Bonventre <andy...@golang.org>
Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
Gerrit-Comment-Date: Mon, 09 Jul 2018 22:33:39 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: Yes
Gerrit-MessageType: comment

Brad Fitzpatrick (Gerrit)

unread,
Jul 9, 2018, 6:41:57 PM7/9/18
to Brad Fitzpatrick, goph...@pubsubhelper.golang.org, Michael Piatek, Ian Lance Taylor, Andrew Bonventre, golang-co...@googlegroups.com

Uploaded patch set 2.

(2 comments)

View Change

2 comments:

  • File src/net/http/httputil/reverseproxy.go:

    • Patch Set #1, Line 258: log.Printf("suppressing panic for copyResponse error in test; copy error: %v", err)

      Is there a way to suppress this logging? (In our prod servers, this will be very common, occurring w […]

      This won't log in production. This is only for the path where the panic is skipped for Go 1.10 test compatibility.

    • Patch Set #1, Line 285: func shouldPanicOnCopyError(req *http.Request) bool {

      Delete this line.

      Done

To view, visit change 122819. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: Ic1fa8405fd54c858ce8c797cec79d006833a9f7d
Gerrit-Change-Number: 122819
Gerrit-PatchSet: 2
Gerrit-Owner: Brad Fitzpatrick <brad...@golang.org>
Gerrit-Reviewer: Andrew Bonventre <andy...@golang.org>
Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
Gerrit-CC: Michael Piatek <pia...@google.com>
Gerrit-Comment-Date: Mon, 09 Jul 2018 22:41:55 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Ian Lance Taylor <ia...@golang.org>
Comment-In-Reply-To: Michael Piatek <pia...@google.com>
Gerrit-MessageType: comment

Brad Fitzpatrick (Gerrit)

unread,
Jul 9, 2018, 6:41:57 PM7/9/18
to Brad Fitzpatrick, Ian Lance Taylor, Andrew Bonventre, goph...@pubsubhelper.golang.org, Michael Piatek, golang-co...@googlegroups.com

Brad Fitzpatrick uploaded patch set #2 to this change.

View Change

net/http/httputil: don't panic in ReverseProxy unless running under a Server

Prior to the fix to #23643, the ReverseProxy didn't panic with
ErrAbortHandler when the copy to a client failed.

During Go 1.11 beta testing, we found plenty of code using
ReverseProxy in tests that were unprepared for a panic.

Change the behavior to only panic when running under the http.Server
that'll handle the panic.

Updates #23643

Change-Id: Ic1fa8405fd54c858ce8c797cec79d006833a9f7d
---
M src/net/http/httputil/reverseproxy.go
M src/net/http/httputil/reverseproxy_test.go
2 files changed, 28 insertions(+), 1 deletion(-)

To view, visit change 122819. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: Ic1fa8405fd54c858ce8c797cec79d006833a9f7d
Gerrit-Change-Number: 122819
Gerrit-PatchSet: 2
Gerrit-Owner: Brad Fitzpatrick <brad...@golang.org>
Gerrit-Reviewer: Andrew Bonventre <andy...@golang.org>
Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
Gerrit-CC: Michael Piatek <pia...@google.com>
Gerrit-MessageType: newpatchset

Brad Fitzpatrick (Gerrit)

unread,
Jul 9, 2018, 6:42:41 PM7/9/18
to Brad Fitzpatrick, goph...@pubsubhelper.golang.org, Michael Piatek, Ian Lance Taylor, Andrew Bonventre, golang-co...@googlegroups.com

Patch set 2:Run-TryBot +1

View Change

    To view, visit change 122819. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: Ic1fa8405fd54c858ce8c797cec79d006833a9f7d
    Gerrit-Change-Number: 122819
    Gerrit-PatchSet: 2
    Gerrit-Owner: Brad Fitzpatrick <brad...@golang.org>
    Gerrit-Reviewer: Andrew Bonventre <andy...@golang.org>
    Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
    Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
    Gerrit-CC: Michael Piatek <pia...@google.com>
    Gerrit-Comment-Date: Mon, 09 Jul 2018 22:42:38 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: Yes
    Gerrit-MessageType: comment

    Gobot Gobot (Gerrit)

    unread,
    Jul 9, 2018, 6:42:51 PM7/9/18
    to Brad Fitzpatrick, goph...@pubsubhelper.golang.org, Michael Piatek, Ian Lance Taylor, Andrew Bonventre, golang-co...@googlegroups.com

    TryBots beginning. Status page: https://farmer.golang.org/try?commit=56f775f9

    View Change

      To view, visit change 122819. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: go
      Gerrit-Branch: master
      Gerrit-Change-Id: Ic1fa8405fd54c858ce8c797cec79d006833a9f7d
      Gerrit-Change-Number: 122819
      Gerrit-PatchSet: 2
      Gerrit-Owner: Brad Fitzpatrick <brad...@golang.org>
      Gerrit-Reviewer: Andrew Bonventre <andy...@golang.org>
      Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
      Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
      Gerrit-CC: Gobot Gobot <go...@golang.org>
      Gerrit-CC: Michael Piatek <pia...@google.com>
      Gerrit-Comment-Date: Mon, 09 Jul 2018 22:42:48 +0000
      Gerrit-HasComments: No
      Gerrit-Has-Labels: No
      Gerrit-MessageType: comment

      Michael Piatek (Gerrit)

      unread,
      Jul 9, 2018, 6:49:01 PM7/9/18
      to Brad Fitzpatrick, goph...@pubsubhelper.golang.org, Ian Lance Taylor, Andrew Bonventre, golang-co...@googlegroups.com

      View Change

      1 comment:

        • Is there a way to suppress this logging? (In our prod servers, this will be very common, occurring when users close their browser window.)

      To view, visit change 122819. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: go
      Gerrit-Branch: master
      Gerrit-Change-Id: Ic1fa8405fd54c858ce8c797cec79d006833a9f7d
      Gerrit-Change-Number: 122819
      Gerrit-PatchSet: 1
      Gerrit-Owner: Brad Fitzpatrick <brad...@golang.org>
      Gerrit-Reviewer: Andrew Bonventre <andy...@golang.org>
      Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
      Gerrit-CC: Michael Piatek <pia...@google.com>
      Gerrit-Comment-Date: Mon, 09 Jul 2018 22:39:28 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: No
      Gerrit-MessageType: comment

      Gobot Gobot (Gerrit)

      unread,
      Jul 9, 2018, 6:50:37 PM7/9/18
      to Brad Fitzpatrick, goph...@pubsubhelper.golang.org, Michael Piatek, Ian Lance Taylor, Andrew Bonventre, golang-co...@googlegroups.com

      TryBots are happy.

      Patch set 2:TryBot-Result +1

      View Change

        To view, visit change 122819. To unsubscribe, or for help writing mail filters, visit settings.

        Gerrit-Project: go
        Gerrit-Branch: master
        Gerrit-Change-Id: Ic1fa8405fd54c858ce8c797cec79d006833a9f7d
        Gerrit-Change-Number: 122819
        Gerrit-PatchSet: 2
        Gerrit-Owner: Brad Fitzpatrick <brad...@golang.org>
        Gerrit-Reviewer: Andrew Bonventre <andy...@golang.org>
        Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
        Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
        Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
        Gerrit-CC: Michael Piatek <pia...@google.com>
        Gerrit-Comment-Date: Mon, 09 Jul 2018 22:50:35 +0000

        Michael Piatek (Gerrit)

        unread,
        Jul 9, 2018, 6:59:22 PM7/9/18
        to Brad Fitzpatrick, goph...@pubsubhelper.golang.org, Gobot Gobot, Ian Lance Taylor, Andrew Bonventre, golang-co...@googlegroups.com

        View Change

        1 comment:

        • File src/net/http/httputil/reverseproxy.go:

          • Patch Set #1, Line 258: log.Printf("suppressing panic for copyResponse error in test; copy error: %v", err)

            This won't log in production. This is only for the path where the panic is skipped for Go 1. […]

            I might be missing something, but I think we'll up here on our prod code paths. (The panic motivating this change occurs from a call to ServeHTTP outside the stack of an http.Server, so !shouldPanicOnCopyError and this logging IIUC.)

            Feel free to ping me on chat if you'd like to discuss directly.

        To view, visit change 122819. To unsubscribe, or for help writing mail filters, visit settings.

        Gerrit-Project: go
        Gerrit-Branch: master
        Gerrit-Change-Id: Ic1fa8405fd54c858ce8c797cec79d006833a9f7d
        Gerrit-Change-Number: 122819
        Gerrit-PatchSet: 2
        Gerrit-Owner: Brad Fitzpatrick <brad...@golang.org>
        Gerrit-Reviewer: Andrew Bonventre <andy...@golang.org>
        Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
        Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
        Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
        Gerrit-CC: Michael Piatek <pia...@google.com>
        Gerrit-Comment-Date: Mon, 09 Jul 2018 22:59:20 +0000
        Gerrit-HasComments: Yes
        Gerrit-Has-Labels: No
        Comment-In-Reply-To: Brad Fitzpatrick <brad...@golang.org>

        Brad Fitzpatrick (Gerrit)

        unread,
        Jul 9, 2018, 7:03:36 PM7/9/18
        to Brad Fitzpatrick, goph...@pubsubhelper.golang.org, Gobot Gobot, Michael Piatek, Ian Lance Taylor, Andrew Bonventre, golang-co...@googlegroups.com

        Uploaded patch set 3.

        View Change

          To view, visit change 122819. To unsubscribe, or for help writing mail filters, visit settings.

          Gerrit-Project: go
          Gerrit-Branch: master
          Gerrit-Change-Id: Ic1fa8405fd54c858ce8c797cec79d006833a9f7d
          Gerrit-Change-Number: 122819
          Gerrit-PatchSet: 3
          Gerrit-Owner: Brad Fitzpatrick <brad...@golang.org>
          Gerrit-Reviewer: Andrew Bonventre <andy...@golang.org>
          Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
          Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
          Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
          Gerrit-CC: Michael Piatek <pia...@google.com>
          Gerrit-Comment-Date: Mon, 09 Jul 2018 23:03:33 +0000

          Brad Fitzpatrick (Gerrit)

          unread,
          Jul 9, 2018, 7:03:36 PM7/9/18
          to Brad Fitzpatrick, Ian Lance Taylor, Gobot Gobot, Andrew Bonventre, goph...@pubsubhelper.golang.org, Michael Piatek, golang-co...@googlegroups.com

          Brad Fitzpatrick uploaded patch set #3 to this change.

          View Change

          net/http/httputil: don't panic in ReverseProxy unless running under a Server

          Prior to the fix to #23643, the ReverseProxy didn't panic with
          ErrAbortHandler when the copy to a client failed.

          During Go 1.11 beta testing, we found plenty of code using
          ReverseProxy in tests that were unprepared for a panic.

          Change the behavior to only panic when running under the http.Server
          that'll handle the panic.

          Updates #23643

          Change-Id: Ic1fa8405fd54c858ce8c797cec79d006833a9f7d
          ---
          M src/net/http/httputil/reverseproxy.go
          M src/net/http/httputil/reverseproxy_test.go
          2 files changed, 28 insertions(+), 1 deletion(-)

          To view, visit change 122819. To unsubscribe, or for help writing mail filters, visit settings.

          Gerrit-Project: go
          Gerrit-Branch: master
          Gerrit-Change-Id: Ic1fa8405fd54c858ce8c797cec79d006833a9f7d
          Gerrit-Change-Number: 122819
          Gerrit-PatchSet: 3
          Gerrit-Owner: Brad Fitzpatrick <brad...@golang.org>
          Gerrit-Reviewer: Andrew Bonventre <andy...@golang.org>
          Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
          Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
          Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>

          Brad Fitzpatrick (Gerrit)

          unread,
          Jul 9, 2018, 7:40:01 PM7/9/18
          to Brad Fitzpatrick, goph...@pubsubhelper.golang.org, Gobot Gobot, Michael Piatek, Ian Lance Taylor, Andrew Bonventre, golang-co...@googlegroups.com

          View Change

          1 comment:

          • File src/net/http/httputil/reverseproxy.go:

            • Patch Set #1, Line 258: p.logf("suppressing panic for copyResponse error in test; copy error: %v", err)

              I might be missing something, but I think we'll up here on our prod code paths. […]

              Per chat, you'll need to handle ErrAbortHandler yourself if you have an alternate server implementation.

          To view, visit change 122819. To unsubscribe, or for help writing mail filters, visit settings.

          Gerrit-Project: go
          Gerrit-Branch: master
          Gerrit-Change-Id: Ic1fa8405fd54c858ce8c797cec79d006833a9f7d
          Gerrit-Change-Number: 122819
          Gerrit-PatchSet: 3
          Gerrit-Owner: Brad Fitzpatrick <brad...@golang.org>
          Gerrit-Reviewer: Andrew Bonventre <andy...@golang.org>
          Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
          Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
          Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
          Gerrit-CC: Michael Piatek <pia...@google.com>
          Gerrit-Comment-Date: Mon, 09 Jul 2018 23:39:59 +0000

          Brad Fitzpatrick (Gerrit)

          unread,
          Jul 9, 2018, 7:40:05 PM7/9/18
          to Brad Fitzpatrick, goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Gobot Gobot, Michael Piatek, Ian Lance Taylor, Andrew Bonventre, golang-co...@googlegroups.com

          Brad Fitzpatrick merged this change.

          View Change

          Approvals: Ian Lance Taylor: Looks good to me, approved
          net/http/httputil: don't panic in ReverseProxy unless running under a Server

          Prior to the fix to #23643, the ReverseProxy didn't panic with
          ErrAbortHandler when the copy to a client failed.

          During Go 1.11 beta testing, we found plenty of code using
          ReverseProxy in tests that were unprepared for a panic.

          Change the behavior to only panic when running under the http.Server
          that'll handle the panic.

          Updates #23643

          Change-Id: Ic1fa8405fd54c858ce8c797cec79d006833a9f7d
          Reviewed-on: https://go-review.googlesource.com/122819
          Reviewed-by: Ian Lance Taylor <ia...@golang.org>

          ---
          M src/net/http/httputil/reverseproxy.go
          M src/net/http/httputil/reverseproxy_test.go
          2 files changed, 28 insertions(+), 1 deletion(-)

          diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go
          index 2eda6b7..6f0a241 100644

          --- a/src/net/http/httputil/reverseproxy.go
          +++ b/src/net/http/httputil/reverseproxy.go
          @@ -253,7 +253,11 @@
          defer res.Body.Close()
          // Since we're streaming the response, if we run into an error all we can do
          // is abort the request. Issue 23643: ReverseProxy should use ErrAbortHandler
          - // on read error while copying body
          + // on read error while copying body.
          + if !shouldPanicOnCopyError(req) {
          +			p.logf("suppressing panic for copyResponse error in test; copy error: %v", err)

          + return
          + }
          panic(http.ErrAbortHandler)
          }
          res.Body.Close() // close now, instead of defer, to populate res.Trailer
          @@ -271,6 +275,28 @@

          }
          }

          +var inOurTests bool // whether we're in our own tests
          +
          +// shouldPanicOnCopyError reports whether the reverse proxy should
          +// panic with http.ErrAbortHandler. This is the right thing to do by
          +// default, but Go 1.10 and earlier did not, so existing unit tests
          +// weren't expecting panics. Only panic in our own tests, or when
          +// running under the HTTP server.
          Gerrit-PatchSet: 4
          Gerrit-Owner: Brad Fitzpatrick <brad...@golang.org>
          Gerrit-Reviewer: Andrew Bonventre <andy...@golang.org>
          Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
          Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
          Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
          Gerrit-CC: Michael Piatek <pia...@google.com>
          Gerrit-MessageType: merged
          Reply all
          Reply to author
          Forward
          0 new messages