diff --git a/go.mod b/go.mod index 2d6246ed7b..0803551be1 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,3 @@ module golang.org/x/tools -require ( - golang.org/x/net v0.0.0-20190213061140-3a22650c66bd - golang.org/x/sync v0.0.0-20181108010431-42b317875d0f // indirect - google.golang.org/appengine v1.4.0 -) +require golang.org/x/net v0.0.0-20190213061140-3a22650c66bd diff --git a/go.sum b/go.sum index 24edbf4948..9fb0388d64 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,2 @@ -github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd h1:HuTn7WObtcDo9uEEU7rEqL0jYthdXAmZ6PP+meazmaU= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= diff --git a/playground/appengine.go b/playground/appengine.go deleted file mode 100644 index 08c61f3d19..0000000000 --- a/playground/appengine.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2012 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. - -// +build appengine - -package playground - -import ( - "context" - "io" - "net/http" - - "google.golang.org/appengine" - "google.golang.org/appengine/log" - "google.golang.org/appengine/urlfetch" -) - -func init() { - onAppengine = !appengine.IsDevAppServer() -} - -func contextFunc(r *http.Request) context.Context { - return appengine.NewContext(r) -} - -func post(ctx context.Context, url, contentType string, body io.Reader) (*http.Response, error) { - return urlfetch.Client(ctx).Post(url, contentType, body) -} - -func report(r *http.Request, err error) { - ctx := appengine.NewContext(r) - log.Errorf(ctx, "%v", err) -} diff --git a/playground/common.go b/playground/common.go deleted file mode 100644 index 564aff1743..0000000000 --- a/playground/common.go +++ /dev/null @@ -1,67 +0,0 @@ -// 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. -package playground // import "golang.org/x/tools/playground" - -import ( - "bytes" - "context" - "errors" - "fmt" - "io" - "net/http" - "time" -) - -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); err != nil { - http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) - report(r, err) - return - } - io.Copy(w, b) -} - -func passThru(w io.Writer, req *http.Request) error { - if req.URL.Path == "/share" && !allowShare(req) { - return errors.New("Forbidden") - } - defer req.Body.Close() - url := baseURL + req.URL.Path - ctx, cancel := context.WithTimeout(contextFunc(req), 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 -} - -var onAppengine = false // will be overridden by appengine.go - -func allowShare(r *http.Request) bool { - if !onAppengine { - return true - } - switch r.Header.Get("X-AppEngine-Country") { - case "", "ZZ", "CN": - return false - } - return true -} diff --git a/playground/local.go b/playground/local.go deleted file mode 100644 index 741ab6f9e7..0000000000 --- a/playground/local.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2012 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. - -// +build !appengine - -package playground - -import ( - "context" - "fmt" - "io" - "log" - "net/http" -) - -func post(ctx context.Context, url, contentType string, body io.Reader) (*http.Response, error) { - req, err := http.NewRequest("POST", 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)) -} - -func contextFunc(_ *http.Request) context.Context { - return context.Background() -} - -func report(r *http.Request, err error) { - log.Println(err) -} diff --git a/playground/playground.go b/playground/playground.go new file mode 100644 index 0000000000..14e9841831 --- /dev/null +++ b/playground/playground.go @@ -0,0 +1,90 @@ +// 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 +}