From 22ef61a8d5f1ce80fd36a48ee441e4276aedcfbc Mon Sep 17 00:00:00 2001 From: erinn Date: Tue, 2 Nov 2021 14:30:03 -0700 Subject: [PATCH 1/4] wip: file retries --- functionality/filesharing/filesharing_functionality.go | 2 +- peer/cwtch_peer.go | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/functionality/filesharing/filesharing_functionality.go b/functionality/filesharing/filesharing_functionality.go index 59f5192..8666ff8 100644 --- a/functionality/filesharing/filesharing_functionality.go +++ b/functionality/filesharing/filesharing_functionality.go @@ -43,7 +43,7 @@ type OverlayMessage struct { // to downloadFilePath func (f *Functionality) DownloadFile(profile peer.CwtchPeer, handle string, downloadFilePath string, manifestFilePath string, key string) { profile.SetAttribute(attr.GetLocalScope(fmt.Sprintf("%s.manifest", key)), manifestFilePath) - profile.SetAttribute(attr.GetLocalScope(key), downloadFilePath) + profile.SetAttribute(attr.GetLocalScope(fmt.Sprintf("%s.path", key)), downloadFilePath) profile.SendGetValToPeer(handle, attr.PublicScope, fmt.Sprintf("%s.manifest.size", key)) } diff --git a/peer/cwtch_peer.go b/peer/cwtch_peer.go index c6f6e97..ff25100 100644 --- a/peer/cwtch_peer.go +++ b/peer/cwtch_peer.go @@ -27,7 +27,7 @@ var autoHandleableEvents = map[event.Type]bool{event.EncryptedGroupMessage: true event.ServerStateChange: true, event.NewGroupInvite: true, event.NewMessageFromPeer: true, event.PeerAcknowledgement: true, event.PeerError: true, event.SendMessageToPeerError: true, event.SendMessageToGroupError: true, event.NewGetValMessageFromPeer: true, event.NewRetValMessageFromPeer: true, event.ProtocolEngineStopped: true, event.RetryServerRequest: true, - event.ManifestSizeReceived: true, event.ManifestReceived: true} + event.ManifestSizeReceived: true, event.ManifestReceived: true, event.FileDownloaded: true} // DefaultEventsToHandle specifies which events will be subscribed to // when a peer has its Init() function called @@ -875,7 +875,9 @@ func (cp *cwtchPeer) eventHandler() { } else { log.Errorf("no download path found for manifest: %v", fileKey) } - + case event.FileDownloaded: + fileKey := ev.Data[event.FileKey] + cp.SetAttribute(fmt.Sprintf("%s.complete", fileKey), "true") case event.NewRetValMessageFromPeer: onion := ev.Data[event.RemotePeer] scope := ev.Data[event.Scope] From bf1a92528a17bffa6f11a410cc68ceec85a4c339 Mon Sep 17 00:00:00 2001 From: erinn Date: Thu, 4 Nov 2021 14:07:43 -0700 Subject: [PATCH 2/4] file resumption support --- .../filesharing/filesharing_functionality.go | 15 ++++++++++----- peer/cwtch_peer.go | 15 ++++++++++++--- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/functionality/filesharing/filesharing_functionality.go b/functionality/filesharing/filesharing_functionality.go index 1099abf..0dae38a 100644 --- a/functionality/filesharing/filesharing_functionality.go +++ b/functionality/filesharing/filesharing_functionality.go @@ -2,19 +2,21 @@ package filesharing import ( "crypto/rand" - "cwtch.im/cwtch/model" - "cwtch.im/cwtch/model/attr" - "cwtch.im/cwtch/peer" - "cwtch.im/cwtch/protocol/files" "encoding/hex" "encoding/json" "errors" "fmt" - "git.openprivacy.ca/openprivacy/log" "io" "math" path "path/filepath" "strconv" + "time" + + "cwtch.im/cwtch/model" + "cwtch.im/cwtch/model/attr" + "cwtch.im/cwtch/peer" + "cwtch.im/cwtch/protocol/files" + "git.openprivacy.ca/openprivacy/log" ) // Functionality groups some common UI triggered functions for contacts... @@ -88,6 +90,9 @@ func (f *Functionality) ShareFile(filepath string, profile peer.CwtchPeer, handl // manifest.FileName gets redacted in filesharing_subsystem (to remove the system-specific file hierarchy), // but we need to *store* the full path because the sender also uses it to locate the file lenDiff := len(filepath) - len(path.Base(filepath)) + + profile.SetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.ts", key), strconv.FormatInt(time.Now().Unix(), 10)) + profile.SetScopedZonedAttribute(attr.ConversationScope, attr.FilesharingZone, fmt.Sprintf("%s.manifest", key), string(serializedManifest)) profile.SetScopedZonedAttribute(attr.ConversationScope, attr.FilesharingZone, fmt.Sprintf("%s.manifest.size", key), strconv.Itoa(int(math.Ceil(float64(len(serializedManifest)-lenDiff)/float64(files.DefaultChunkSize))))) profile.ShareFile(key, string(serializedManifest)) diff --git a/peer/cwtch_peer.go b/peer/cwtch_peer.go index 9020186..da72524 100644 --- a/peer/cwtch_peer.go +++ b/peer/cwtch_peer.go @@ -1,7 +1,6 @@ package peer import ( - "cwtch.im/cwtch/model/constants" "encoding/base32" "encoding/base64" "encoding/json" @@ -13,6 +12,8 @@ import ( "sync" "time" + "cwtch.im/cwtch/model/constants" + "cwtch.im/cwtch/event" "cwtch.im/cwtch/model" "cwtch.im/cwtch/model/attr" @@ -879,6 +880,14 @@ func (cp *cwtchPeer) eventHandler() { val, exists = cp.GetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name) } + if exists && zone == attr.FilesharingZone && strings.HasSuffix(zpath, ".manifest.size") { + fileKey := strings.TrimSuffix(zpath, ".manifest.size") + serializedManifest, exists2 := cp.GetScopedZonedAttribute(attr.ConversationScope, attr.FilesharingZone, fmt.Sprintf("%s.manifest", fileKey)) + if exists2 { + cp.ShareFile(fileKey, serializedManifest) + } + } + resp := event.NewEvent(event.SendRetValMessageToPeer, map[event.Field]string{event.RemotePeer: onion, event.Exists: strconv.FormatBool(exists)}) resp.EventID = ev.EventID if exists { @@ -902,7 +911,7 @@ func (cp *cwtchPeer) eventHandler() { manifestFilePath, exists := cp.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%v.manifest", fileKey)) if exists { - downloadFilePath, exists := cp.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fileKey) + downloadFilePath, exists := cp.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%v.path", fileKey)) if exists { log.Debugf("downloading manifest to %v, file to %v", manifestFilePath, downloadFilePath) var manifest files.Manifest @@ -939,7 +948,7 @@ func (cp *cwtchPeer) eventHandler() { } case event.FileDownloaded: fileKey := ev.Data[event.FileKey] - cp.SetAttribute(fmt.Sprintf("%s.complete", fileKey), "true") + cp.SetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.complete", fileKey), "true") case event.NewRetValMessageFromPeer: onion := ev.Data[event.RemotePeer] scope := ev.Data[event.Scope] From 934bfe4f6927c38f533f3309df9c6793665540c9 Mon Sep 17 00:00:00 2001 From: erinn Date: Thu, 4 Nov 2021 14:28:58 -0700 Subject: [PATCH 3/4] timeout downloads --- peer/cwtch_peer.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/peer/cwtch_peer.go b/peer/cwtch_peer.go index da72524..2ebf6ec 100644 --- a/peer/cwtch_peer.go +++ b/peer/cwtch_peer.go @@ -788,6 +788,13 @@ func (cp *cwtchPeer) storeMessage(onion string, messageTxt string, sent time.Tim } func (cp *cwtchPeer) ShareFile(fileKey string, serializedManifest string) { + tsStr, exists := cp.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.ts", fileKey)) + if exists { + ts, err := strconv.ParseInt(tsStr, 10, 64) + if err != nil || ts < time.Now().Unix()-2592000 { + log.Errorf("ignoring request to download a file offered more than 30 days ago") + }s + } cp.eventBus.Publish(event.NewEvent(event.ShareManifest, map[event.Field]string{event.FileKey: fileKey, event.SerializedManifest: serializedManifest})) } From 01a2b7833e9750a76ec77577461cc6894960e1b4 Mon Sep 17 00:00:00 2001 From: erinn Date: Thu, 4 Nov 2021 14:41:00 -0700 Subject: [PATCH 4/4] code type --- peer/cwtch_peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peer/cwtch_peer.go b/peer/cwtch_peer.go index 2ebf6ec..3bc5a9c 100644 --- a/peer/cwtch_peer.go +++ b/peer/cwtch_peer.go @@ -793,7 +793,7 @@ func (cp *cwtchPeer) ShareFile(fileKey string, serializedManifest string) { ts, err := strconv.ParseInt(tsStr, 10, 64) if err != nil || ts < time.Now().Unix()-2592000 { log.Errorf("ignoring request to download a file offered more than 30 days ago") - }s + } } cp.eventBus.Publish(event.NewEvent(event.ShareManifest, map[event.Field]string{event.FileKey: fileKey, event.SerializedManifest: serializedManifest})) }