+++ /dev/null
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package playground registers HTTP handlers at "/compile" and "/share" that
-// proxy requests to the golang.org playground service.
-// This package may be used unaltered on App Engine Standard with Go 1.11+ runtime.
-package playground // import "golang.org/x/tools/playground"
-
-import (
- "bytes"
- "context"
- "fmt"
- "io"
- "log"
- "net/http"
- "os"
- "strings"
- "time"
-
- "golang.org/x/tools/godoc/golangorgenv"
-)
-
-const baseURL = "https://play.golang.org"
-
-func init() {
- http.HandleFunc("/compile", bounce)
- http.HandleFunc("/share", bounce)
-}
-
-func bounce(w http.ResponseWriter, r *http.Request) {
- b := new(bytes.Buffer)
- if err := passThru(b, r); os.IsPermission(err) {
- http.Error(w, "403 Forbidden", http.StatusForbidden)
- log.Println(err)
- return
- } else if err != nil {
- http.Error(w, "500 Internal Server Error", http.StatusInternalServerError)
- log.Println(err)
- return
- }
- io.Copy(w, b)
-}
-
-func passThru(w io.Writer, req *http.Request) error {
- if req.URL.Path == "/share" && googleCN(req) {
- return os.ErrPermission
- }
- defer req.Body.Close()
- url := baseURL + req.URL.Path
- ctx, cancel := context.WithTimeout(req.Context(), 60*time.Second)
- defer cancel()
- r, err := post(ctx, url, req.Header.Get("Content-Type"), req.Body)
- if err != nil {
- return fmt.Errorf("making POST request: %v", err)
- }
- defer r.Body.Close()
- if _, err := io.Copy(w, r.Body); err != nil {
- return fmt.Errorf("copying response Body: %v", err)
- }
- return nil
-}
-
-func post(ctx context.Context, url, contentType string, body io.Reader) (*http.Response, error) {
- req, err := http.NewRequest(http.MethodPost, url, body)
- if err != nil {
- return nil, fmt.Errorf("http.NewRequest: %v", err)
- }
- req.Header.Set("Content-Type", contentType)
- return http.DefaultClient.Do(req.WithContext(ctx))
-}
-
-// googleCN reports whether request r is considered
-// to be served from golang.google.cn.
-func googleCN(r *http.Request) bool {
- if r.FormValue("googlecn") != "" {
- return true
- }
- if strings.HasSuffix(r.Host, ".cn") {
- return true
- }
- if !golangorgenv.CheckCountry() {
- return false
- }
- switch r.Header.Get("X-Appengine-Country") {
- case "", "ZZ", "CN":
- return true
- }
- return false
-}