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 <percy@tailscale.com>
This commit is contained in:
Percy Wegmann
2024-03-19 21:54:37 -05:00
committed by Percy Wegmann
parent 0d8cd1645a
commit bed818a978
5 changed files with 300 additions and 17 deletions
+21 -3
View File
@@ -67,8 +67,9 @@ const (
NotifyInitialPrefs // if set, the first Notify message (sent immediately) will contain the current Prefs
NotifyInitialNetMap // if set, the first Notify message (sent immediately) will contain the current NetMap
NotifyNoPrivateKeys // if set, private keys that would normally be sent in updates are zeroed out
NotifyInitialTailFSShares // if set, the first Notify message (sent immediately) will contain the current TailFS Shares
NotifyNoPrivateKeys // if set, private keys that would normally be sent in updates are zeroed out
NotifyInitialTailFSShares // if set, the first Notify message (sent immediately) will contain the current TailFS Shares
NotifyInitialOutgoingFiles // if set, the first Notify message (sent immediately) will contain the current Taildrop OutgoingFiles
)
// Notify is a communication from a backend (e.g. tailscaled) to a frontend
@@ -114,6 +115,11 @@ type Notify struct {
// Deprecated: use LocalClient.AwaitWaitingFiles instead.
IncomingFiles []PartialFile `json:",omitempty"`
// OutgoingFiles, if non-nil, tracks which files are in the process of
// being sent via TailDrop, including files that finished, whether
// successful or failed. This slice is sorted by Started time, then Name.
OutgoingFiles []*OutgoingFile `json:",omitempty"`
// LocalTCPPort, if non-nil, informs the UI frontend which
// (non-zero) localhost TCP port it's listening on.
// This is currently only used by Tailscale when run in the
@@ -175,7 +181,7 @@ func (n Notify) String() string {
return s[0:len(s)-1] + "}"
}
// PartialFile represents an in-progress file transfer.
// PartialFile represents an in-progress incoming file transfer.
type PartialFile struct {
Name string // e.g. "foo.jpg"
Started time.Time // time transfer started
@@ -194,6 +200,18 @@ type PartialFile struct {
Done bool `json:",omitempty"`
}
// OutgoingFile represents an in-progress outgoing file transfer.
type OutgoingFile struct {
ID string `json:"-"` // unique identifier for this transfer (a type 4 UUID)
PeerID tailcfg.StableNodeID // identifier for the peer to which this is being transferred
Name string `json:",omitempty"` // e.g. "foo.jpg"
Started time.Time // time transfer started
DeclaredSize int64 // or -1 if unknown
Sent int64 // bytes copied thus far
Finished bool // indicates whether or not the transfer finished
Succeeded bool // for a finished transfer, indicates whether or not it was successful
}
// StateKey is an opaque identifier for a set of LocalBackend state
// (preferences, private keys, etc.). It is also used as a key for
// the various LoginProfiles that the instance may be signed into.