diff --git a/cmd/godoc/regtest_test.go b/cmd/godoc/regtest_test.go index 7e76017069..f7c7219a4d 100644 --- a/cmd/godoc/regtest_test.go +++ b/cmd/godoc/regtest_test.go @@ -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) diff --git a/godoc/proxy/proxy.go b/godoc/proxy/proxy.go index 1c1798f0fe..bb0e81c3c4 100644 --- a/godoc/proxy/proxy.go +++ b/godoc/proxy/proxy.go @@ -11,11 +11,10 @@ import ( "context" "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 {