I’m stuck on Stage #CN2
Here are the logs when I push my code:
remote: [tester::#CN2] Sent bytes: "GET /echo/raspberry HTTP/1.1\r\nHost: localhost:4221\r\n\r\n"
remote: [your_program] line: GET /echo/raspberry HTTP/1.1
remote: [your_program] Request: GET /echo/raspberry HTTP/1.1
remote: [your_program] -> else if
remote: [tester::#CN2] Failed to read response:
remote: [tester::#CN2] Received: "" (no content received)
remote: [tester::#CN2] ^ error
remote: [tester::#CN2] Error: Expected: HTTP-version, Received: ""
remote: [tester::#CN2] Test failed
But when I do the same request on my computer I get it right:
➜ curl -v localhost:4221/echo/raspberry
* Trying 127.0.0.1:4221...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 4221 (#0)
> GET /echo/raspberry HTTP/1.1
> Host: localhost:4221
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: text/plain
< Content-Length: 9
<
* Connection #0 to host localhost left intact
raspberry%
This is my code, I add some printf
for debuging:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#define PORT 4221
#define BUF_SIZE 512
#define TARGET_ECHO "/echo"
struct http_request {
char *method;
char *request_target;
char *protocol;
};
int main() {
// Disable output buffering
setbuf(stdout, NULL);
setbuf(stderr, NULL);
// You can use print statements as follows for debugging, they'll be visible when running tests.
printf("Logs from your program will appear here!\n");
// Uncomment this block to pass the first stage
int server_fd, client_addr_len, client_fd;
struct sockaddr_in client_addr;
char buf[BUF_SIZE];
ssize_t nread;
char *request_line;
struct http_request request;
char *echo;
server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd == -1) {
fprintf(stderr, "Socket creation failed: %s...\n", strerror(errno));
exit(EXIT_FAILURE);
}
// Since the tester restarts your program quite often, setting SO_REUSEADDR
// ensures that we don't run into 'Address already in use' errors
int reuse = 1;
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) {
fprintf(stderr, "SO_REUSEADDR failed: %s \n", strerror(errno));
exit(EXIT_FAILURE);
}
struct sockaddr_in serv_addr = { .sin_family = AF_INET ,
.sin_port = htons(PORT),
.sin_addr = { htonl(INADDR_ANY) },
};
if (bind(server_fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) != 0) {
fprintf(stderr, "Bind failed: %s \n", strerror(errno));
exit(EXIT_FAILURE);
}
int connection_backlog = 5;
if (listen(server_fd, connection_backlog) != 0) {
fprintf(stderr, "Listen failed: %s \n", strerror(errno));
exit(EXIT_FAILURE);
}
printf("Waiting for a client to connect...\n");
client_addr_len = sizeof(client_addr);
char *response;
client_fd = accept(server_fd, (struct sockaddr *) &client_addr, &client_addr_len);
if (client_fd < 0) {
fprintf(stderr, "Accept failed: %s \n", strerror(errno));
exit(EXIT_FAILURE);
}
printf("Client connected\n");
nread = recv(client_fd, buf, BUF_SIZE, 0);
if (nread < 0) {
fprintf(stderr, "Recv failed: %s \n", strerror(errno));
exit(EXIT_FAILURE);
}
// parsing the "request-line"
request_line = strtok(buf, "\r\n");
printf("line: %s\n", request_line);
request.method = strtok(request_line, " ");
request.request_target = strtok(NULL, " ");
request.protocol = strtok(NULL, " ");
printf("Request: %s %s %s\n", request.method, request.request_target, request.protocol);
if (strcmp(request.request_target, "/") == 0) {
printf(" -> if\n");
response = "HTTP/1.1 200 OK\r\n\r\n";
} else if (strncmp(request.request_target, TARGET_ECHO, strlen(TARGET_ECHO)) == 0){
printf(" -> else if\n");
echo = strtok(request.request_target, "/");
echo = strtok(NULL, "/");
sprintf(response,
"HTTP/1.1 200 OK\
\r\n\
Content-Type: text/plain\r\n\
Content-Length: %ld\r\n\
\r\n\
%s", strlen(echo), echo);
} else {
printf(" -> else\n");
response = "HTTP/1.1 404 Not Found\r\n\r\n";
}
printf("Response: %s\n", response);
if(send(client_fd, response, strlen(response), 0) < 0) {
fprintf(stderr, "Send failed: %s \n", strerror(errno));
}
close(client_fd);
close(server_fd);
return 0;
}
My printf("Response: %s\n", response);
it’s never printing, so it’s like the program on the test never runs after sprintf
statement.