forked from Silverfish/proton-bridge
fix (GODT-597): duplicate send when draft creation takes a long time
This commit is contained in:
@ -4,8 +4,6 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/)
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
## [v1.3.x] Emma (beta since 2020-08-05)
|
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
* GODT-633 Persistent anonymous API cookies for better load balancing and abuse detection.
|
* GODT-633 Persistent anonymous API cookies for better load balancing and abuse detection.
|
||||||
|
|
||||||
@ -40,9 +38,10 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/)
|
|||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
* GODT-454 Fix send on closed channel when receiving unencrypted send confirmation from GUI.
|
* GODT-454 Fix send on closed channel when receiving unencrypted send confirmation from GUI.
|
||||||
|
* GODT-597 Duplicate sending when draft creation takes too long
|
||||||
|
|
||||||
|
|
||||||
## [v1.3.x] Emma (beta 2020-07-XXX)
|
## [v1.3.x] Emma (v1.3.2 beta 2020-08-04, v1.3.3 beta 2020-08-06, v1.3.3 live 2020-08-12)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
* GODT-554 Detect and notify about "bad certificate" IMAP TLS error.
|
* GODT-554 Detect and notify about "bad certificate" IMAP TLS error.
|
||||||
|
|||||||
@ -69,14 +69,31 @@ func (q *sendRecorder) getMessageHash(message *pmapi.Message) string {
|
|||||||
return fmt.Sprintf("%x", h.Sum(nil))
|
return fmt.Sprintf("%x", h.Sum(nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *sendRecorder) addMessage(hash, messageID string) {
|
func (q *sendRecorder) addMessage(hash string) {
|
||||||
q.lock.Lock()
|
q.lock.Lock()
|
||||||
defer q.lock.Unlock()
|
defer q.lock.Unlock()
|
||||||
|
|
||||||
q.deleteExpiredKeys()
|
q.deleteExpiredKeys()
|
||||||
q.hashes[hash] = sendRecorderValue{
|
q.hashes[hash] = sendRecorderValue{
|
||||||
messageID: messageID,
|
time: time.Now(),
|
||||||
time: time.Now(),
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *sendRecorder) removeMessage(hash string) {
|
||||||
|
q.lock.Lock()
|
||||||
|
defer q.lock.Unlock()
|
||||||
|
|
||||||
|
q.deleteExpiredKeys()
|
||||||
|
delete(q.hashes, hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *sendRecorder) setMessageID(hash, messageID string) {
|
||||||
|
q.lock.Lock()
|
||||||
|
defer q.lock.Unlock()
|
||||||
|
|
||||||
|
if val, ok := q.hashes[hash]; ok {
|
||||||
|
val.messageID = messageID
|
||||||
|
q.hashes[hash] = val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,6 +106,12 @@ func (q *sendRecorder) isSendingOrSent(client messageGetter, hash string) (isSen
|
|||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we have a value but don't yet have a messageID, we are in the process of uploading the draft.
|
||||||
|
if value.messageID == "" {
|
||||||
|
return true, false
|
||||||
|
}
|
||||||
|
|
||||||
message, err := client.GetMessage(value.messageID)
|
message, err := client.GetMessage(value.messageID)
|
||||||
// Message could be deleted or there could be an internet issue or whatever,
|
// Message could be deleted or there could be an internet issue or whatever,
|
||||||
// so let's assume the message was not sent.
|
// so let's assume the message was not sent.
|
||||||
@ -107,7 +130,8 @@ func (q *sendRecorder) isSendingOrSent(client messageGetter, hash string) (isSen
|
|||||||
if message.Type == pmapi.MessageTypeSent || message.Type == pmapi.MessageTypeInboxAndSent {
|
if message.Type == pmapi.MessageTypeSent || message.Type == pmapi.MessageTypeInboxAndSent {
|
||||||
wasSent = true
|
wasSent = true
|
||||||
}
|
}
|
||||||
return
|
|
||||||
|
return isSending, wasSent
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *sendRecorder) deleteExpiredKeys() {
|
func (q *sendRecorder) deleteExpiredKeys() {
|
||||||
|
|||||||
@ -365,7 +365,8 @@ func TestSendRecorder_getMessageHash(t *testing.T) {
|
|||||||
|
|
||||||
func TestSendRecorder_isSendingOrSent(t *testing.T) {
|
func TestSendRecorder_isSendingOrSent(t *testing.T) {
|
||||||
q := newSendRecorder()
|
q := newSendRecorder()
|
||||||
q.addMessage("hash", "messageID")
|
q.addMessage("hash")
|
||||||
|
q.setMessageID("hash", "messageID")
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
hash string
|
hash string
|
||||||
|
|||||||
@ -230,11 +230,13 @@ func (su *smtpUser) Send(from string, to []string, messageReader io.Reader) (err
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
su.backend.sendRecorder.addMessage(sendRecorderMessageHash)
|
||||||
message, atts, err := su.storeUser.CreateDraft(kr, message, attReaders, attachedPublicKey, attachedPublicKeyName, parentID)
|
message, atts, err := su.storeUser.CreateDraft(kr, message, attReaders, attachedPublicKey, attachedPublicKeyName, parentID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
su.backend.sendRecorder.removeMessage(sendRecorderMessageHash)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
su.backend.sendRecorder.addMessage(sendRecorderMessageHash, message.ID)
|
su.backend.sendRecorder.setMessageID(sendRecorderMessageHash, message.ID)
|
||||||
|
|
||||||
// We always have to create a new draft even if there already is one,
|
// We always have to create a new draft even if there already is one,
|
||||||
// because clients don't necessarily save the draft before sending, which
|
// because clients don't necessarily save the draft before sending, which
|
||||||
|
|||||||
Reference in New Issue
Block a user