I’m stuck on Stage #AP6.
I’ve tried adding fs.existsSync() in the equation and still nothing changes. Logically it should catch the error and send 404 Not Found, but looks like there is an issue somewhere.
Here are my logs:
remote: Debug = true
remote:
remote: [tester::#AP6] Running tests for Stage #AP6 (Return a file)
remote: [tester::#AP6] Running program
remote: [tester::#AP6] $ ./your_server.sh --directory /tmp/data/codecrafters.io/http-server-tester/
remote: [tester::#AP6] Testing existing file
remote: [tester::#AP6] Creating file pear_raspberry_banana_apple in /tmp/data/codecrafters.io/http-server-tester/
remote: [tester::#AP6] File Content: "apple grape blueberry apple raspberry blueberry strawberry mango"
remote: [tester::#AP6] Connected to localhost port 4221
remote: [tester::#AP6] $ curl -v http://localhost:4221/files/pear_raspberry_banana_apple
remote: [tester::#AP6] > GET /files/pear_raspberry_banana_apple HTTP/1.1
remote: [tester::#AP6] > Host: localhost:4221
remote: [tester::#AP6] >
remote: [tester::#AP6] Sent bytes: "GET /files/pear_raspberry_banana_apple HTTP/1.1\r\nHost: localhost:4221\r\n\r\n"
remote: [your_program] Client connected
remote: [your_program] http is : GET /files/pear_raspberry_banana_apple HTTP/1.1
remote: [your_program] Host: localhost:4221
remote: [your_program]
remote: [your_program]
remote: [your_program] [ '', 'files', 'pear_raspberry_banana_apple' ]
remote: [your_program] /tmp/data/codecrafters.io/http-server-tester/
remote: [your_program] pear_raspberry_banana_apple
remote: [your_program] /tmp/data/codecrafters.io/http-server-tester/pear_raspberry_banana_apple
remote: [your_program] La douille !
remote: [tester::#AP6] Received bytes: "HTTP/1.1 200 OK\r\nContent-Type: application/octet-stream\r\nContent-Length: 64\r\n\r\napple grape blueberry apple raspberry blueberry strawberry mango"
remote: [tester::#AP6] < HTTP/1.1 200 OK
remote: [tester::#AP6] < Content-Type: application/octet-stream
remote: [tester::#AP6] < Content-Length: 64
remote: [tester::#AP6] <
remote: [tester::#AP6] < apple grape blueberry apple raspberry blueberry strawberry mango
remote: [tester::#AP6] <
remote: [tester::#AP6] Received response with 200 status code
remote: [tester::#AP6] ✓ Content-Type header is present
remote: [tester::#AP6] ✓ Content-Length header is present
remote: [tester::#AP6] ✓ Body is correct
remote: [tester::#AP6] First test passed.
remote: [tester::#AP6] Testing non existent file returns 404
remote: [tester::#AP6] Connected to localhost port 4221
remote: [tester::#AP6] $ curl -v http://localhost:4221/files/non-existentapple_blueberry_orange_apple
remote: [tester::#AP6] > GET /files/non-existentapple_blueberry_orange_apple HTTP/1.1
remote: [tester::#AP6] > Host: localhost:4221
remote: [tester::#AP6] >
remote: [tester::#AP6] Sent bytes: "GET /files/non-existentapple_blueberry_orange_apple HTTP/1.1\r\nHost: localhost:4221\r\n\r\n"
remote: [tester::#AP6] Failed to read response:
remote: [tester::#AP6] Received: "" (no content received)
remote: [tester::#AP6] ^ error
remote: [tester::#AP6] Error: Expected: HTTP-version, Received: ""
remote: [tester::#AP6] Test failed
remote: [tester::#AP6] Terminating program
remote: [tester::#AP6] Program terminated successfully
And here’s a snippet of my code:
function parseHeaders(http) {
const lines = http.split("\r\n");
const headers = {};
lines.slice(1).forEach((line) => {
const [key, value] = line.split(": ");
headers[key] = value;
});
return headers;
}
function handleRequest(socket, http) {
const headers = parseHeaders(http);
const [method, path] = http.split("\r\n")[0].split(" ");
// console.log("Path is : " + path);
const pathSegments = path.split("/");
console.log(pathSegments);
switch (pathSegments[1]) {
case "echo":
const body = pathSegments[2];
sendResponse(socket, HTTP_STATUS_OK, body, "text/plain");
break;
case "user-agent":
const userAgent = headers["User-Agent"];
sendResponse(socket, HTTP_STATUS_OK, userAgent);
break;
case "files":
const directory = process.argv[3];
console.log(directory);
const filename = pathSegments[2];
console.log(filename);
const filePath = `${directory}${filename}`;
console.log(filePath);
try {
if (!fs.existsSync(filePath)) throw new Error();
const fileContent = fs.readFileSync(filePath).toString();
sendResponse(
socket,
HTTP_STATUS_OK,
fileContent,
"application/octet-stream"
);
} catch (err) {
socket.write("HTTP/1.1 404 Not Found\r\n\r\n");
}
socket.write("HTTP/1.1 404 Not Found\r\n\r\n");
break;
case "":
socket.write(`HTTP/1.1 200 OK\r\n\r\n`);
break;
default:
socket.write(`HTTP/1.1 404 Not Found\r\n\r\n`);
}
}
function sendResponse(socket, status, body = "", contentType) {
const response = `HTTP/1.1 ${status}\r\nContent-Type: ${contentType}\r\nContent-Length: ${body.length}\r\n\r\n${body}`;
socket.write(response);
}
const server = net.createServer((socket) => {
console.log("Client connected");
socket.on("data", (data) => {
const http = data.toString();
console.log("http is : " + http);
handleRequest(socket, http);
});
socket.on("close", () => {
socket.end();
server.close();
});
});
Thanks in advance for the help !