cmd/tailscale/cli: add debug mode to push slowly for testing

Also set Content-Length when known, and fail explicitly on sending
directories for now.

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
pull/1679/head
Brad Fitzpatrick 4 years ago
parent a9a3d3b4c1
commit 6a7912e37a

@ -17,10 +17,12 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
"strconv"
"time" "time"
"unicode/utf8" "unicode/utf8"
"github.com/peterbourgon/ff/v2/ffcli" "github.com/peterbourgon/ff/v2/ffcli"
"golang.org/x/time/rate"
"tailscale.com/ipn" "tailscale.com/ipn"
"tailscale.com/ipn/ipnstate" "tailscale.com/ipn/ipnstate"
) )
@ -62,6 +64,7 @@ func runPush(ctx context.Context, args []string) error {
var fileContents io.Reader var fileContents io.Reader
var name = pushArgs.name var name = pushArgs.name
var contentLength int64 = -1
if fileArg == "-" { if fileArg == "-" {
fileContents = os.Stdin fileContents = os.Stdin
if name == "" { if name == "" {
@ -76,10 +79,22 @@ func runPush(ctx context.Context, args []string) error {
return err return err
} }
defer f.Close() defer f.Close()
fileContents = f fi, err := f.Stat()
if err != nil {
return err
}
if fi.IsDir() {
return errors.New("directories not supported")
}
contentLength = fi.Size()
fileContents = io.LimitReader(f, contentLength)
if name == "" { if name == "" {
name = fileArg name = fileArg
} }
if slow, _ := strconv.ParseBool(os.Getenv("TS_DEBUG_SLOW_PUSH")); slow {
fileContents = &slowReader{r: fileContents}
}
} }
dstURL := "http://" + net.JoinHostPort(ip, fmt.Sprint(peerAPIPort)) + "/v0/put/" + url.PathEscape(name) dstURL := "http://" + net.JoinHostPort(ip, fmt.Sprint(peerAPIPort)) + "/v0/put/" + url.PathEscape(name)
@ -87,6 +102,7 @@ func runPush(ctx context.Context, args []string) error {
if err != nil { if err != nil {
return err return err
} }
req.ContentLength = contentLength
if pushArgs.verbose { if pushArgs.verbose {
log.Printf("sending to %v ...", dstURL) log.Printf("sending to %v ...", dstURL)
} }
@ -171,3 +187,22 @@ func pickStdinFilename() (name string, r io.Reader, err error) {
} }
return "stdin" + ext(sniff), io.MultiReader(bytes.NewReader(sniff), os.Stdin), nil return "stdin" + ext(sniff), io.MultiReader(bytes.NewReader(sniff), os.Stdin), nil
} }
type slowReader struct {
r io.Reader
rl *rate.Limiter
}
func (r *slowReader) Read(p []byte) (n int, err error) {
const burst = 4 << 10
plen := len(p)
if plen > burst {
plen = burst
}
if r.rl == nil {
r.rl = rate.NewLimiter(rate.Limit(1<<10), burst)
}
n, err = r.r.Read(p[:plen])
r.rl.WaitN(context.Background(), n)
return
}

Loading…
Cancel
Save