1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Package playground registers an HTTP handler at "/compile" that
6 // proxies requests to the golang.org playground service.
7 // This package may be used unaltered on App Engine Standard with Go 1.11+ runtime.
8 package playground // import "golang.org/x/tools/playground"
20 const baseURL = "https://play.golang.org"
23 http.Handle("/compile", Proxy())
26 // Proxy returns a handler that can be registered on /compile to proxy requests to the Go playground.
28 // This package already contains a func init that does:
31 // http.Handle("/compile", Proxy())
34 // Proxy may be useful for servers that use HTTP muxes other than the default mux.
35 func Proxy() http.Handler {
36 return http.HandlerFunc(bounce)
39 func bounce(w http.ResponseWriter, r *http.Request) {
40 b := new(bytes.Buffer)
41 if err := passThru(b, r); err != nil {
42 http.Error(w, "500 Internal Server Error", http.StatusInternalServerError)
49 func passThru(w io.Writer, req *http.Request) error {
50 defer req.Body.Close()
51 url := baseURL + req.URL.Path
52 ctx, cancel := context.WithTimeout(req.Context(), 60*time.Second)
54 r, err := post(ctx, url, req.Header.Get("Content-Type"), req.Body)
56 return fmt.Errorf("making POST request: %v", err)
59 if _, err := io.Copy(w, r.Body); err != nil {
60 return fmt.Errorf("copying response Body: %v", err)
65 func post(ctx context.Context, url, contentType string, body io.Reader) (*http.Response, error) {
66 req, err := http.NewRequest(http.MethodPost, url, body)
68 return nil, fmt.Errorf("http.NewRequest: %v", err)
70 req.Header.Set("Content-Type", contentType)
71 return http.DefaultClient.Do(req.WithContext(ctx))