Skip to content

Commit 45496a0

Browse files
committed
Ensure strict resp clients
This is a fix for the new '-o json' flag to ensure certain standard redis clients continue to use the standard pubsub SUBSCRIBE message response. See #779
1 parent f6e6fae commit 45496a0

File tree

3 files changed

+25
-5
lines changed

3 files changed

+25
-5
lines changed

internal/server/client.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ type Client struct {
1919
replAddr string // the known replication addr for follower connections
2020
authd bool // client has been authenticated
2121
outputType Type // Null, JSON, or RESP
22+
strictRESP bool // client is in strict RESP mode
2223
remoteAddr string // original remote address
2324
in InputStream // input stream
2425
pr PipelineReader // command reader

internal/server/pubsub.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ func (s *Server) liveSubscription(
189189
connType := msg.ConnType
190190
if websocket {
191191
outputType = JSON
192+
} else if msg.StrictRESP {
193+
outputType = RESP
192194
}
193195

194196
var start time.Time

internal/server/server.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,7 @@ func (s *Server) netServe() error {
692692
} else if defaultOutputType != Null {
693693
msg.OutputType = defaultOutputType
694694
}
695+
msg.StrictRESP = client.strictRESP
695696
if msg.Command() == "quit" {
696697
if msg.OutputType == RESP {
697698
io.WriteString(client, "+OK\r\n")
@@ -752,6 +753,7 @@ func (s *Server) netServe() error {
752753
}
753754

754755
client.outputType = msg.OutputType
756+
client.strictRESP = msg.StrictRESP
755757
} else {
756758
client.Write([]byte("HTTP/1.1 500 Bad Request\r\nConnection: close\r\n\r\n"))
757759
break
@@ -1113,20 +1115,29 @@ func (s *Server) handleInputCommand(client *Client, msg *Message) error {
11131115

11141116
if cmd == "hello" {
11151117
// Not Supporting RESP3+, returns an ERR instead.
1116-
ot, ct := msg.OutputType, msg.ConnType
1117-
if len(msg.Args) > 1 && (msg.Args[1] >= "0" && msg.Args[1] <= "9") &&
1118-
s.opts.ClientOutput == "json" && ot == JSON && ct == RESP {
1118+
ot := msg.OutputType
1119+
if len(msg.Args) > 1 && (msg.Args[1] >= "0" &&
1120+
msg.Args[1] <= "9") && s.opts.ClientOutput == "json" &&
1121+
ot == JSON && msg.ConnType == RESP {
11191122
// Here we are making sure that we ignoring the '-o json' flag, if
11201123
// used, otherwise the connection will fail for some redis clients
11211124
// like "github.com/redis/go-redis/v9" are overly strict and expect
11221125
// a map type or an error as the result of the HELLO command.
1123-
msg.OutputType, msg.ConnType = RESP, RESP
1126+
msg.OutputType = RESP
1127+
msg.StrictRESP = true
11241128
}
11251129
err := writeErr("unknown command '" + msg.Args[0] + "'")
1126-
msg.OutputType, msg.ConnType = ot, ct
1130+
msg.OutputType = ot
11271131
return err
11281132
}
11291133

1134+
if cmd == "command" && len(msg.Args) > 1 && msg.Args[1] == "DOCS" &&
1135+
s.opts.ClientOutput == "json" {
1136+
// The standard Redis client typically sends a "COMMAND DOCS" to start
1137+
// client connection.
1138+
msg.StrictRESP = true
1139+
}
1140+
11301141
if cmd == "timeout" {
11311142
if err := rewriteTimeoutMsg(msg); err != nil {
11321143
return writeErr(err.Error())
@@ -1550,6 +1561,7 @@ const (
15501561
type Message struct {
15511562
_command string
15521563
Args []string
1564+
StrictRESP bool
15531565
ConnType Type
15541566
OutputType Type
15551567
Auth string
@@ -1622,6 +1634,7 @@ func readNextHTTPCommand(packet []byte, argsIn [][]byte, msg *Message, wr io.Wri
16221634
args = argsIn[:0]
16231635
msg.ConnType = HTTP
16241636
msg.OutputType = JSON
1637+
msg.StrictRESP = false
16251638
opacket := packet
16261639

16271640
ready, err := func() (bool, error) {
@@ -1734,6 +1747,7 @@ func readNextHTTPCommand(packet []byte, argsIn [][]byte, msg *Message, wr io.Wri
17341747
}
17351748
msg.AcceptEncoding = acceptEncoding
17361749
msg.OutputType = JSON
1750+
msg.StrictRESP = false
17371751
msg.Args = nmsg.Args
17381752
return true, nil
17391753
}()
@@ -1806,12 +1820,15 @@ moreData:
18061820
case redcon.Redis:
18071821
msg.ConnType = RESP
18081822
msg.OutputType = RESP
1823+
msg.StrictRESP = false
18091824
case redcon.Tile38:
18101825
msg.ConnType = Native
18111826
msg.OutputType = JSON
1827+
msg.StrictRESP = false
18121828
case redcon.Telnet:
18131829
msg.ConnType = RESP
18141830
msg.OutputType = RESP
1831+
msg.StrictRESP = false
18151832
}
18161833
msgs = append(msgs, msg)
18171834
}

0 commit comments

Comments
 (0)