Skip to content

Commit db03ff4

Browse files
Merge pull request #160 from drakkan/multiline_resp
add support for multi-line replies
2 parents 2a131bc + cf92f67 commit db03ff4

File tree

2 files changed

+85
-3
lines changed

2 files changed

+85
-3
lines changed

client_handler.go

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -259,9 +259,15 @@ func (c *clientHandler) writeLine(line string) {
259259
}
260260

261261
func (c *clientHandler) writeMessage(code int, message string) {
262-
message = strings.ReplaceAll(message, "\n", "\\n")
263-
message = strings.ReplaceAll(message, "\r", "\\r")
264-
c.writeLine(fmt.Sprintf("%d %s", code, message))
262+
lines := getMessageLines(message)
263+
264+
for idx, line := range lines {
265+
if idx < len(lines)-1 {
266+
c.writeLine(fmt.Sprintf("%d-%s", code, line))
267+
} else {
268+
c.writeLine(fmt.Sprintf("%d %s", code, line))
269+
}
270+
}
265271
}
266272

267273
// ErrNoPassiveConnectionDeclared is defined when a transfer is openeed without any passive connection declared
@@ -334,3 +340,18 @@ func (c *clientHandler) multilineAnswer(code int, message string) func() {
334340
c.writeLine(fmt.Sprintf("%d End", code))
335341
}
336342
}
343+
344+
func getMessageLines(message string) []string {
345+
lines := make([]string, 0, 1)
346+
sc := bufio.NewScanner(strings.NewReader(message))
347+
348+
for sc.Scan() {
349+
lines = append(lines, sc.Text())
350+
}
351+
352+
if len(lines) == 0 {
353+
lines = append(lines, "")
354+
}
355+
356+
return lines
357+
}

client_handler_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,64 @@ func TestConcurrency(t *testing.T) {
3737

3838
waitGroup.Wait()
3939
}
40+
41+
type multilineMessage struct {
42+
message string
43+
expectedLines []string
44+
}
45+
46+
func TestMultiLineMessages(t *testing.T) {
47+
testMultilines := []multilineMessage{
48+
{
49+
message: "single line",
50+
expectedLines: []string{"single line"},
51+
},
52+
{
53+
message: "",
54+
expectedLines: []string{""},
55+
},
56+
{
57+
message: "first line\r\nsecond line\r\n",
58+
expectedLines: []string{"first line", "second line"},
59+
},
60+
{
61+
message: "first line\nsecond line\n",
62+
expectedLines: []string{"first line", "second line"},
63+
},
64+
{
65+
message: "first line\rsecond line",
66+
expectedLines: []string{"first line\rsecond line"},
67+
},
68+
{
69+
message: `first line
70+
71+
second line
72+
73+
`,
74+
expectedLines: []string{"first line", "", "second line", ""},
75+
},
76+
}
77+
78+
for _, msg := range testMultilines {
79+
lines := getMessageLines(msg.message)
80+
if len(lines) != len(msg.expectedLines) {
81+
t.Errorf("unexpected number of lines got: %v want: %v", len(lines), len(msg.expectedLines))
82+
}
83+
84+
for _, line := range lines {
85+
if !isStringInSlice(line, msg.expectedLines) {
86+
t.Errorf("unexpected line %#v", line)
87+
}
88+
}
89+
}
90+
}
91+
92+
func isStringInSlice(s string, list []string) bool {
93+
for _, c := range list {
94+
if s == c {
95+
return true
96+
}
97+
}
98+
99+
return false
100+
}

0 commit comments

Comments
 (0)