Skip to content

Commit

Permalink
support duplicate tags during resend (#6)
Browse files Browse the repository at this point in the history
* send raw body bytes when doing a resend

* always set body bytes

* add test, rename

---------

Co-authored-by: Vikas Khurana <[email protected]>
  • Loading branch information
vakhurana and Vikas Khurana authored Mar 6, 2023
1 parent 8de72de commit 7cd1cb6
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 4 deletions.
2 changes: 1 addition & 1 deletion in_session.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ func (state inSession) resendMessages(session *session, beginSeqNo, endSeqNo int
}

session.log.OnEventf("Resending Message: %v", sentMessageSeqNum)
msgBytes = msg.build()
msgBytes = msg.buildFromBodyBytes()
session.EnqueueBytesAndSend(msgBytes)

seqNum = sentMessageSeqNum + 1
Expand Down
31 changes: 28 additions & 3 deletions message.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,14 +212,14 @@ func ParseMessageWithDataDictionary(
trailerBytes = rawBytes
msg.Body.add(msg.fields[fieldIndex : fieldIndex+1])
}
if parsedFieldBytes.tag == tagCheckSum {
break
}

if !foundBody {
msg.bodyBytes = rawBytes
}

if parsedFieldBytes.tag == tagCheckSum {
break
}
fieldIndex++
}

Expand Down Expand Up @@ -373,9 +373,34 @@ func (m *Message) build() []byte {
return b.Bytes()
}

// introduced to work around issue with resending messages with repeating groups
// issue described: https://github.com/quickfixgo/quickfix/issues/276
func (m *Message) buildFromBodyBytes() []byte {
m.cookFromBodyBytes()

var b bytes.Buffer
m.Header.write(&b)
b.Write(m.bodyBytes)
m.Trailer.write(&b)
return b.Bytes()
}

func (m *Message) cook() {
bodyLength := m.Header.length() + m.Body.length() + m.Trailer.length()
m.Header.SetInt(tagBodyLength, bodyLength)
checkSum := (m.Header.total() + m.Body.total() + m.Trailer.total()) % 256
m.Trailer.SetString(tagCheckSum, formatCheckSum(checkSum))
}

func (m *Message) cookFromBodyBytes() {
bodyLength := m.Header.length() + len(m.bodyBytes) + m.Trailer.length()
m.Header.SetInt(tagBodyLength, bodyLength)

bodyTotal := 0
for _, b := range []byte(m.bodyBytes) {
bodyTotal += int(b)
}

checkSum := (m.Header.total() + bodyTotal + m.Trailer.total()) % 256
m.Trailer.SetString(tagCheckSum, formatCheckSum(checkSum))
}
9 changes: 9 additions & 0 deletions message_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,15 @@ func (s *MessageSuite) TestParseOutOfOrder() {
s.Nil(ParseMessage(s.msg, rawMsg))
}

func (s *MessageSuite) TestRoundtripBuildFromBodyBytes() {
expected := bytes.NewBufferString("8=FIX.4.29=14235=D34=143=Y49=ISLD52=20230305-21:16:44.00256=TW122=20230305-21:16:44.00211=11=tag1group12=tag2group112=11=tag1group22=tag2group210=099")
err := ParseMessage(s.msg, expected)
s.NoError(err)

actual := s.msg.buildFromBodyBytes()
s.Equal(expected.Bytes(), actual)
}

func (s *MessageSuite) TestBuild() {
s.msg.Header.SetField(tagBeginString, FIXString(BeginStringFIX44))
s.msg.Header.SetField(tagMsgType, FIXString("A"))
Expand Down

0 comments on commit 7cd1cb6

Please sign in to comment.