vendor: update all dependencies

This commit is contained in:
Nick Craig-Wood
2018-06-17 17:59:12 +01:00
parent 3f0789e2db
commit 08021c4636
2474 changed files with 435818 additions and 282709 deletions
+128
View File
@@ -0,0 +1,128 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// httpr is a proxy that can record or replay HTTP requests.
// Start httpr with either the -record or -replay flags, providing a filename.
// Terminate the process with an interrupt (kill -2) to write the log file when recording.
// To get the CA certificate of the proxy, issue a GET to http://localhost:CP/authority.cer, where
// CP is the control port.
// +build go1.8
package main
import (
"encoding/base64"
"flag"
"fmt"
"io/ioutil"
"log"
"net"
"net/http"
"os"
"os/signal"
"cloud.google.com/go/httpreplay/internal/proxy"
"github.com/google/martian/martianhttp"
)
var (
port = flag.Int("port", 8080, "port of the proxy")
controlPort = flag.Int("control-port", 8181, "port for controlling the proxy")
record = flag.String("record", "", "record traffic and save to filename")
replay = flag.String("replay", "", "read filename and replay traffic")
debugHeaders = flag.Bool("debug-headers", false, "log header mismatches")
)
func main() {
flag.Parse()
if *record == "" && *replay == "" {
log.Fatal("provide either -record or -replay")
}
if *record != "" && *replay != "" {
log.Fatal("provide only one of -record and -replay")
}
log.Printf("httpr: starting proxy on port %d and control on port %d", *port, *controlPort)
var pr *proxy.Proxy
var err error
if *record != "" {
pr, err = proxy.ForRecording(*record, *port)
} else {
pr, err = proxy.ForReplaying(*replay, *port)
}
if err != nil {
log.Fatal(err)
}
proxy.DebugHeaders = *debugHeaders
// Expose handlers on the control port.
mux := http.NewServeMux()
mux.Handle("/authority.cer", martianhttp.NewAuthorityHandler(pr.CACert))
mux.HandleFunc("/initial", handleInitial(pr))
lControl, err := net.Listen("tcp", fmt.Sprintf(":%d", *controlPort))
if err != nil {
log.Fatal(err)
}
go http.Serve(lControl, mux)
sigc := make(chan os.Signal, 1)
signal.Notify(sigc, os.Interrupt)
<-sigc
log.Println("httpr: shutting down")
if err := pr.Close(); err != nil {
log.Fatal(err)
}
}
func handleInitial(pr *proxy.Proxy) http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
switch req.Method {
case "GET":
if pr.Initial != nil {
switch x := pr.Initial.(type) {
case []byte:
w.Write(x)
case string:
// If it's base64, then it's most likely from the JSON in the saved file
// (json.Marshal encodes []byte as a base64 string). Decode it.
if bytes, err := base64.StdEncoding.DecodeString(x); err == nil {
w.Write(bytes)
} else {
// If it's not base64, write the string out directly.
w.Write([]byte(x))
}
default:
// We don't know what it is, so just print it.
fmt.Fprint(w, x)
}
}
case "POST":
bytes, err := ioutil.ReadAll(req.Body)
req.Body.Close()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, "reading body: %v", err)
}
pr.Initial = bytes
default:
w.WriteHeader(http.StatusBadRequest)
fmt.Fprint(w, "use GET to retrieve initial or POST to set it")
}
}
}
+230
View File
@@ -0,0 +1,230 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build go1.8
package main_test
import (
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/url"
"os"
"os/exec"
"strings"
"testing"
"time"
"cloud.google.com/go/internal/testutil"
"cloud.google.com/go/storage"
"golang.org/x/net/context"
"golang.org/x/oauth2"
"google.golang.org/api/option"
)
const initial = "initial state"
func TestIntegration_HTTPR(t *testing.T) {
if testing.Short() {
t.Skip("Integration tests skipped in short mode")
}
if testutil.ProjID() == "" {
t.Fatal("set GCLOUD_TESTS_GOLANG_PROJECT_ID and GCLOUD_TESTS_GOLANG_KEY")
}
// Get a unique temporary filename.
f, err := ioutil.TempFile("", "httpreplay")
if err != nil {
t.Fatal(err)
}
replayFilename := f.Name()
if err := f.Close(); err != nil {
t.Fatal(err)
}
defer os.Remove(replayFilename)
if err := exec.Command("go", "build").Run(); err != nil {
t.Fatalf("running 'go build': %v", err)
}
defer os.Remove("./httpr")
want := runRecord(t, replayFilename)
got := runReplay(t, replayFilename)
if got != want {
t.Fatalf("got %q, want %q", got, want)
}
}
func runRecord(t *testing.T, filename string) string {
cmd, tr, cport, err := start("-record", filename)
if err != nil {
t.Fatal(err)
}
defer stop(t, cmd)
ctx := context.Background()
hc := &http.Client{
Transport: &oauth2.Transport{
Base: tr,
Source: testutil.TokenSource(ctx, storage.ScopeFullControl),
},
}
res, err := http.Post(
fmt.Sprintf("http://localhost:%s/initial", cport),
"text/plain",
strings.NewReader(initial))
if err != nil {
t.Fatal(err)
}
if res.StatusCode != 200 {
t.Fatalf("from POST: %s", res.Status)
}
info, err := getBucketInfo(ctx, hc)
if err != nil {
t.Fatal(err)
}
return info
}
func runReplay(t *testing.T, filename string) string {
cmd, tr, cport, err := start("-replay", filename)
if err != nil {
t.Fatal(err)
}
defer stop(t, cmd)
hc := &http.Client{Transport: tr}
res, err := http.Get(fmt.Sprintf("http://localhost:%s/initial", cport))
if err != nil {
t.Fatal(err)
}
if res.StatusCode != 200 {
t.Fatalf("from GET: %s", res.Status)
}
bytes, err := ioutil.ReadAll(res.Body)
res.Body.Close()
if err != nil {
t.Fatal(err)
}
if got, want := string(bytes), initial; got != want {
t.Errorf("initial: got %q, want %q", got, want)
}
info, err := getBucketInfo(context.Background(), hc)
if err != nil {
t.Fatal(err)
}
return info
}
// Start the proxy binary and wait for it to come up.
// Return a transport that talks to the proxy, as well as the control port.
// modeFlag must be either "-record" or "-replay".
func start(modeFlag, filename string) (*exec.Cmd, *http.Transport, string, error) {
pport, err := pickPort()
if err != nil {
return nil, nil, "", err
}
cport, err := pickPort()
if err != nil {
return nil, nil, "", err
}
cmd := exec.Command("./httpr", "-port", pport, "-control-port", cport, modeFlag, filename, "-debug-headers")
if err := cmd.Start(); err != nil {
return nil, nil, "", err
}
// Wait for the server to come up.
serverUp := false
for i := 0; i < 10; i++ {
if conn, err := net.Dial("tcp", "localhost:"+cport); err == nil {
conn.Close()
serverUp = true
break
}
time.Sleep(time.Second)
}
if !serverUp {
return nil, nil, "", errors.New("server never came up")
}
tr, err := proxyTransport(pport, cport)
if err != nil {
return nil, nil, "", err
}
return cmd, tr, cport, nil
}
func stop(t *testing.T, cmd *exec.Cmd) {
if err := cmd.Process.Signal(os.Interrupt); err != nil {
t.Fatal(err)
}
}
// pickPort picks an unused port.
func pickPort() (string, error) {
l, err := net.Listen("tcp", ":0")
if err != nil {
return "", err
}
addr := l.Addr().String()
_, port, err := net.SplitHostPort(addr)
if err != nil {
return "", err
}
l.Close()
return port, nil
}
func proxyTransport(pport, cport string) (*http.Transport, error) {
caCert, err := getBody(fmt.Sprintf("http://localhost:%s/authority.cer", cport))
if err != nil {
return nil, err
}
caCertPool := x509.NewCertPool()
if !caCertPool.AppendCertsFromPEM([]byte(caCert)) {
return nil, errors.New("bad CA Cert")
}
return &http.Transport{
Proxy: http.ProxyURL(&url.URL{Host: "localhost:" + pport}),
TLSClientConfig: &tls.Config{RootCAs: caCertPool},
}, nil
}
func getBucketInfo(ctx context.Context, hc *http.Client) (string, error) {
client, err := storage.NewClient(ctx, option.WithHTTPClient(hc))
if err != nil {
return "", err
}
defer client.Close()
b := client.Bucket(testutil.ProjID())
attrs, err := b.Attrs(ctx)
if err != nil {
return "", err
}
return fmt.Sprintf("name:%s reqpays:%v location:%s sclass:%s",
attrs.Name, attrs.RequesterPays, attrs.Location, attrs.StorageClass), nil
}
func getBody(url string) ([]byte, error) {
res, err := http.Get(url)
if err != nil {
return nil, err
}
if res.StatusCode != 200 {
return nil, fmt.Errorf("response: %s", res.Status)
}
defer res.Body.Close()
return ioutil.ReadAll(res.Body)
}