#include #include #include #include #include #include #include #include #include #include #include #include int shsd_sendfile(int in_fd, FILE *ou_fd) { struct stat s; int stat_result = fstat(fileno(ou_fd), &s); if (stat_result != 0) { perror("fstat"); return -1; } sendfile(in_fd, fileno(ou_fd), NULL, s.st_size); return 0; } return 0; } int main(int argc, char **argv) { struct addrinfo hints, *res, *servinfo; struct sockaddr_storage their_addr; socklen_t addr_size; int sockfd, new_fd; int yes = 1; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; // use IPv4 or IPv6, whichever hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; // fill in my IP for me getaddrinfo(NULL, argv[1], &hints, &res); sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } if (bind(sockfd, res->ai_addr, res->ai_addrlen) == -1) { perror("bind"); close(sockfd); exit(1); } if (listen(sockfd, 10) == -1) { perror("listen"); close(sockfd); exit(1); } addr_size = sizeof(their_addr); char buf[1024]; memset(buf, 0, 1024); int recv_result; while (1) { new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &addr_size); recv_result = recv(new_fd, (void *)buf, 1024, 0); if (recv_result == -1) { perror("recv"); return -1; } if (strncmp(buf, "GET", 3) == 0) { char *http_status = "HTTP/1.1 200 OK\r\n"; char *http_content_type = "text/html\r\n\r\n"; printf("Received GET request.\n"); send(new_fd, http_status, strlen(http_status), 0); send(new_fd, http_content_type, strlen(http_content_type), 0); FILE *index_fd = fopen("./index.html", "r"); struct stat stat_buf; shsd_sendfile(new_fd, index_fd, &stat_buf); } memset(buf, 0, 1024); close(new_fd); } close(sockfd); close(new_fd); return 0; }