Single and double quotes when testing redis-cli

I’m stuck on Stage #(Implement the ECHO command #QQ0).

Seems like there is a problem with single quote and double quotes when sending the commands to CLI.

If it is sent with single quotes:

echo -ne '*2\r\n$4\r\nECHO\r\n$10\r\nstrawberry\r\n' | nc localhost 6379

Then all is parsed successfully and code prints something like this:

*2
$4
ECHO
$10
strawberry

But when it is sent with double quotes:

echo -ne "*2\r\n$4\r\nECHO\r\n$10\r\nstrawberry\r\n" | nc localhost 6379

It looks like this:

*2

ECHO

strawberry

Then the $4 and $10 are wiped, because they are treated like special character (bash - Why quotes are retained in string variables when surrounded by single quotes? - Unix & Linux Stack Exchange).

Here are my logs:

Debug = true

[tester::#QQ0] Running tests for Stage #QQ0 (Implement the ECHO command)
[tester::#QQ0] $ ./spawn_redis_server.sh
[your_program] Server listening on port: 6379
[tester::#QQ0] $ redis-cli ECHO pear
[tester::#QQ0] Sent bytes: "*2\r\n$4\r\nECHO\r\n$10\r\nstrawberry\r\n"
[your_program] Creating Redis CLI client thread: 1
[your_program] Starting Redis CLI client thread: 1
[your_program] Running Redis CLI client thread: 1
[tester::#QQ0] Received: "" (no content received)
[tester::#QQ0]            ^ error
[tester::#QQ0] Error: Expected start of a new RESP2 value (either +, -, :, $ or *)
[tester::#QQ0] Test failed
[tester::#QQ0] Terminating program
[tester::#QQ0] Program terminated successfully

And here’s a snippet of my Main.java:

import commandprocessor.RedisCommandParser;
import commandprocessor.RedisRespParser;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.List;

import static commandprocessor.util.InputStreamUtil.getInputStreamBytes;

public class RedisCliThread implements Runnable {

    private final Socket clientSocket;
    private final String threadName;
    private final RedisCommandParser commandParser;
    private final RedisRespParser respParser;
    private Thread thread;

    public RedisCliThread(Socket clientSocket, String threadName) {
        this.clientSocket = clientSocket;
        this.threadName = threadName;
        this.commandParser = new RedisCommandParser();
        this.respParser = new RedisRespParser();

        System.out.println("Creating " + threadName);
    }

    @Override
    public void run() {
        System.out.println("Running " + this.threadName);

        // Wait for connection from client.
        try (InputStream inputStream = this.clientSocket.getInputStream()) {
            byte[] clientInput = getInputStreamBytes(inputStream);
            List<String> parsedParts = respParser.parse(clientInput);
            byte[] result = commandParser.parse(parsedParts);

            if (result != null) {
                this.clientSocket.getOutputStream().write(result);
            }
        } catch (IOException e) {
            System.err.println("IOException while reading input from client: " + e.getMessage());
        } finally {
            closeClientSocket(this.clientSocket);
        }
    }

    public void start() {
        System.out.println("Starting " + this.threadName);

        if (thread == null) {
            thread = new Thread(this);
            thread.start();
        }
    }

    private static void closeClientSocket(Socket clientSocket) {
        try {
            clientSocket.close();
        } catch (IOException e) {
            System.err.println("IOException while closing client socket: " + e.getMessage());
        }
    }
}

I’ve tried to use BufferedReader with InputStreamReader then appending every line to StringBuilder, but the result was the same. the $ was removed.

Looked something like this:

BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line).append("\n");
            }

I am sure I am missing something out…

Any help would be appreciated!
Thank you!

You should use redis-cli instead of netcat, redis-cli will send the correctly formated request to your server.

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.