From bed818a9785fb6f7fa71004f41219ccd2371f9ae Mon Sep 17 00:00:00 2001 From: Percy Wegmann Date: Tue, 19 Mar 2024 21:54:37 -0500 Subject: ipn/localapi: add support for multipart POST to file-put This allows sending multiple files via Taildrop in one request. Progress is tracked via ipn.Notify. Updates tailscale/corp#18202 Signed-off-by: Percy Wegmann --- util/progresstracking/progresstracking.go | 39 +++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 util/progresstracking/progresstracking.go (limited to 'util/progresstracking/progresstracking.go') diff --git a/util/progresstracking/progresstracking.go b/util/progresstracking/progresstracking.go new file mode 100644 index 000000000..a9411fb46 --- /dev/null +++ b/util/progresstracking/progresstracking.go @@ -0,0 +1,39 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package progresstracking provides wrappers around io.Reader and io.Writer +// that track progress. +package progresstracking + +import ( + "io" + "time" +) + +// NewReader wraps the given Reader with a progress tracking Reader that +// reports progress at the following points: +// +// - First read +// - Every read spaced at least interval since the prior read +// - Last read +func NewReader(r io.Reader, interval time.Duration, onProgress func(totalRead int, err error)) io.Reader { + return &reader{Reader: r, interval: interval, onProgress: onProgress} +} + +type reader struct { + io.Reader + interval time.Duration + onProgress func(int, error) + lastTracked time.Time + totalRead int +} + +func (r *reader) Read(p []byte) (int, error) { + n, err := r.Reader.Read(p) + r.totalRead += n + if time.Since(r.lastTracked) > r.interval || err != nil { + r.onProgress(r.totalRead, err) + r.lastTracked = time.Now() + } + return n, err +} -- cgit v1.3-3-g829e