Persistent connection #ag9 : handle the response of second request

I’m stuck on Stage Persistent connection.

Here are my logs after the second request:

remote: [tester::#AG9] Failed to read response:
remote: [tester::#AG9] Received: "" (no content received)
remote: [tester::#AG9]            ^ error
remote: [tester::#AG9] Error: Expected: HTTP-version, Received: ""
remote: [tester::#AG9] Test failed
remote: [tester::#AG9] Terminating program
remote: [tester::#AG9] Program terminated successfully

And here’s a snippet of my code:

 socket.on("data", async (data) => {
    req += data.toString();

    while (req.includes("\r\n\r\n")) {
      const [raw, ...rest] = req.split("\r\n\r\n");

      const headers = raw.split("\r\n").reduce((acc, line) => {
        const [key, value] = line.split(": ");
        if (key && value) acc[key] = value;
        return acc;
      }, {});
      const path = raw.split(" ")[1];
      if (path === "/") {
        socket.write("HTTP/1.1 200 OK\r\n\r\n");
      } else if (path.startsWith("/files/")) {
        const directory = process.argv[3];
        const filename = path.split("/files/")[1];
        let res;
        if (raw.includes("POST")) {
          const content = getBody(raw);
          res = await postFileRequest(filename, content);
        }
        if (existsSync(`${directory}/${filename}`)) {
          const content = readFileSync(`${directory}/${filename}`).toString();
          const res = `HTTP/1.1 200 OK\r\nContent-Type: application/octet-stream\r\nContent-Length: ${content.length}\r\n\r\n${content}\r\n`;
          socket.write(res);
        } else {
          socket.write("HTTP/1.1 404 Not Found\r\n\r\n");
        }
      } else if (path === "/user-agent") {
        if (headers["User-Agent"]) {
          const res = headers["User-Agent"];

          socket.write(`HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: ${res.length}\r\n\r\n${res}\r\n`);
        }
      } else if (path.startsWith("/echo/")) {
        let body = path.split("/echo/")[1];
        const contentEncoding = getAcceptContent(raw);

        if (contentEncoding) {
          const content = gzipSync(body);
          const data = new Buffer.from(content);
          body = contentEncoding.includes("gzip") ? data : body;

          socket.write(
            `HTTP/1.1 200 OK\r\n${contentEncoding ? "Content-Encoding: " + contentEncoding : ""}\r\nContent-Type: text/plain\r\nContent-Length: ${
              body.length
            }\r\n\r\n`
          );
          socket.write(data);
        }

        socket.write(`HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: ${body.length}\r\n\r\n${body}\r\n\r`);
      } else {
        socket.write("HTTP/1.1 404 Not Found\r\n\r\n");
      }

      if (headers["Connection"] && headers["Connection"].toLowerCase() === "close") {
        socket.end();
      }
      req = rest.join("");
    }
  });

Hey @enzo-mir, could you upload your code to GitHub and share the link? It will be much easier to debug if I can run it directly.

Hey ! thanks for answering :
Git link

@enzo-mir, looks like you’ve got past this stage. Do you happen to remember what was wrong? Would love to see if we can improve the tester / instructions.

I passed it but with some lucks beacause i was working on it and just by adding a “console.log()” and commit it it passed but i know I have not the good result.
The error was always on the second request ‘GET /’, the tester get '\r\n\rHTTP/1.1 200 OK\r\n\r\n' instead of HTTP/1.1 200 OK\r\n\r\n so the error (i guess) was about handling multiple request can disturbe the response and concat with the old one.
now I’m stuck at the next stage with the same problem, that’s why i didn’t solved it …

@enzo-mir The error stems from extra \r\n at the end of previous responses: