[release-branch.go1.11] godoc/proxy: remove use of httputil.ReverseProxy for /share
ReverseProxy doesn't re-set the Request's Host field, only
Request.URL.Host.
The HTTP/2 client prefers Request.Host over Request.URL.Host, so this
results in the request being sent back to the host that originally
accepted the request.
This results in an infinite redirect (and consumption of many connections to
itself).
See Issue golang/go#28168 for details.
Replace it with a simple proxy that drops all the headers (except
Content-Type).
I tried setting the proxy.Director, but it still didn't work. Could do
with some more investigation.
Fixes golang/go#28134.
Change-Id: I5051ce72a379dcacfbe8484f58f8cf7d9385024d
Reviewed-on: https://go-review.googlesource.com/c/141718
Run-TryBot: Chris Broadfoot <cbro@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
(cherry picked from commit 837e80568c
)
Reviewed-on: https://go-review.googlesource.com/c/153858
Run-TryBot: Andrew Bonventre <andybons@golang.org>
This commit is contained in:
parent
37bde98e6a
commit
147f5680bc
|
@ -36,6 +36,7 @@ func TestLiveServer(t *testing.T) {
|
|||
Regexp string
|
||||
NoAnalytics bool // expect the response to not contain GA.
|
||||
PostBody string
|
||||
StatusCode int // if 0, expect 2xx status code.
|
||||
}{
|
||||
{
|
||||
Path: "/doc/faq",
|
||||
|
@ -65,6 +66,7 @@ func TestLiveServer(t *testing.T) {
|
|||
Substring: "bdb10cf",
|
||||
Message: "no change redirect - hg to git mapping not registered?",
|
||||
NoAnalytics: true,
|
||||
StatusCode: 302,
|
||||
},
|
||||
{
|
||||
Path: "/dl/",
|
||||
|
@ -81,6 +83,7 @@ func TestLiveServer(t *testing.T) {
|
|||
Path: "/s/go2design",
|
||||
Regexp: "proposal.*Found",
|
||||
NoAnalytics: true,
|
||||
StatusCode: 302,
|
||||
},
|
||||
{
|
||||
Message: "incorrect search result - broken index?",
|
||||
|
@ -105,6 +108,12 @@ func TestLiveServer(t *testing.T) {
|
|||
Regexp: `^{"Errors":"","Events":\[{"Message":"A","Kind":"stdout","Delay":0},{"Message":"B","Kind":"stdout","Delay":1000000000}\]}$`,
|
||||
NoAnalytics: true,
|
||||
},
|
||||
{
|
||||
Path: "/share",
|
||||
PostBody: "package main",
|
||||
Substring: "", // just check it is a 2xx.
|
||||
NoAnalytics: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range substringTests {
|
||||
|
@ -126,6 +135,13 @@ func TestLiveServer(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("RoundTrip: %v", err)
|
||||
}
|
||||
if tc.StatusCode == 0 {
|
||||
if resp.StatusCode > 299 {
|
||||
t.Errorf("Non-OK status code: %v", resp.StatusCode)
|
||||
}
|
||||
} else if tc.StatusCode != resp.StatusCode {
|
||||
t.Errorf("StatusCode; got %v, want %v", resp.StatusCode, tc.StatusCode)
|
||||
}
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Fatalf("ReadAll: %v", err)
|
||||
|
|
|
@ -10,11 +10,10 @@ import (
|
|||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -24,13 +23,6 @@ import (
|
|||
|
||||
const playgroundURL = "https://play.golang.org"
|
||||
|
||||
var proxy *httputil.ReverseProxy
|
||||
|
||||
func init() {
|
||||
target, _ := url.Parse(playgroundURL)
|
||||
proxy = httputil.NewSingleHostReverseProxy(target)
|
||||
}
|
||||
|
||||
type Request struct {
|
||||
Body string
|
||||
}
|
||||
|
@ -136,7 +128,28 @@ func share(w http.ResponseWriter, r *http.Request) {
|
|||
http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
proxy.ServeHTTP(w, r)
|
||||
|
||||
// HACK(cbro): use a simple proxy rather than httputil.ReverseProxy because of Issue #28168.
|
||||
// TODO: investigate using ReverseProxy with a Director, unsetting whatever's necessary to make that work.
|
||||
req, _ := http.NewRequest("POST", playgroundURL+"/share", r.Body)
|
||||
req.Header.Set("Content-Type", r.Header.Get("Content-Type"))
|
||||
req = req.WithContext(r.Context())
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
log.Printf("ERROR share error: %v", err)
|
||||
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
copyHeader := func(k string) {
|
||||
if v := resp.Header.Get(k); v != "" {
|
||||
w.Header().Set(k, v)
|
||||
}
|
||||
}
|
||||
copyHeader("Content-Type")
|
||||
copyHeader("Content-Length")
|
||||
defer resp.Body.Close()
|
||||
w.WriteHeader(resp.StatusCode)
|
||||
io.Copy(w, resp.Body)
|
||||
}
|
||||
|
||||
func googleCN(r *http.Request) bool {
|
||||
|
|
Loading…
Reference in New Issue