Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <unistd.h>
- volatile sig_atomic_t is_sigterm_caught = 0;
- volatile sig_atomic_t is_sigint_caught = 0;
- void handle_sigterm(int signum) {
- is_sigterm_caught = 1;
- }
- void handle_sigint(int signum) {
- is_sigint_caught = 1;
- }
- void send_content_info(int handler_sock_fd, int requested_file_fd) {
- struct stat st;
- fstat(requested_file_fd, &st);
- const int file_size = (int)(st.st_size);
- const int MAX_FILE_SIZE_DIGIT_COUNT = 4096;
- char content_length[MAX_FILE_SIZE_DIGIT_COUNT];
- sprintf(content_length, "Content-Length: %d\r\n\r\n", file_size);
- send(handler_sock_fd, content_length, strlen(content_length), 0);
- const int MESS_PORTION_SIZE = 4096;
- char file_content[MESS_PORTION_SIZE];
- ssize_t read_byte_count = 0;
- while ((read_byte_count = read(requested_file_fd, file_content, sizeof(file_content))) > 0) {
- ssize_t written_byte_count = 0;
- while (written_byte_count != read_byte_count) {
- ssize_t byte_count = write(handler_sock_fd, file_content + written_byte_count,
- (size_t)(read_byte_count - written_byte_count));
- written_byte_count += byte_count;
- }
- }
- }
- void send_execution_info(int handler_sock_fd, char* file_to_execute) {
- pid_t pid = fork();
- if (pid == 0) {
- dup2(handler_sock_fd, 1);
- int has_error_occured = execl(file_to_execute, file_to_execute, NULL);
- if (has_error_occured == -1) {
- perror("file is not executed");
- return;
- }
- } else {
- int status = 0;
- waitpid(pid, &status, 0);
- }
- }
- void send_answer(int handler_sock_fd, char* requested_file_name, char* dir_path) {
- int dir_fd = open(dir_path, O_DIRECTORY);
- int is_existing_file = faccessat(dir_fd, requested_file_name, F_OK, 0);
- if (is_existing_file == -1) {
- char file_status[] = "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n";
- send(handler_sock_fd, file_status, strlen(file_status), 0);
- close(dir_fd);
- return;
- }
- int is_read_allowed = faccessat(dir_fd, requested_file_name, R_OK, 0);
- if (is_read_allowed == -1) {
- char file_status[] = "HTTP/1.1 403 Forbidden\r\nContent-Length: 0\r\n\r\n";
- send(handler_sock_fd, file_status, strlen(file_status), 0);
- close(dir_fd);
- return;
- } else {
- char file_status[] = "HTTP/1.1 200 OK\r\n";
- send(handler_sock_fd, file_status, strlen(file_status), 0);
- }
- int is_executable_file = faccessat(dir_fd, requested_file_name, X_OK, 0);
- if (is_executable_file == -1) {
- int requested_file_fd = openat(dir_fd, requested_file_name, O_RDONLY);
- close(dir_fd);
- send_content_info(handler_sock_fd, requested_file_fd);
- close(requested_file_fd);
- } else {
- close(dir_fd);
- char file_to_execute[PATH_MAX];
- strcat(file_to_execute, dir_path);
- strcat(file_to_execute, "/");
- strcat(file_to_execute, requested_file_name);
- printf("%s\n", file_to_execute);
- fflush(stdout);
- send_execution_info(handler_sock_fd, file_to_execute);
- }
- }
- bool is_time_to_terminate() {
- return is_sigterm_caught == 1 || is_sigint_caught == 1;
- }
- int main(int argc, char** argv)
- {
- struct sigaction sigterm_handler;
- sigterm_handler.sa_handler = &handle_sigterm;
- sigaction(SIGTERM, &sigterm_handler, NULL);
- struct sigaction sigint_handler;
- sigint_handler.sa_handler = &handle_sigint;
- sigaction(SIGINT, &sigint_handler, NULL);
- uint16_t port = (uint16_t)(strtoll(argv[1], NULL, 10));
- int listen_sock_fd = socket(AF_INET, SOCK_STREAM, 0);
- const struct sockaddr_in server_addr = {
- .sin_family = AF_INET,
- .sin_port = htons(port),
- .sin_addr = {.s_addr = inet_addr("127.0.0.1")}
- };
- bind(listen_sock_fd, (const struct sockaddr*)(&server_addr),
- (socklen_t)(sizeof(server_addr)));
- listen(listen_sock_fd, SOMAXCONN);
- int handler_sock_fd = 0;
- while(!is_time_to_terminate()) {
- handler_sock_fd = accept(listen_sock_fd, NULL, NULL);
- if (handler_sock_fd == -1) {
- if (is_time_to_terminate()) {
- close(listen_sock_fd);
- exit(0);
- } else {
- continue;
- }
- }
- FILE* handler_sock = fdopen(handler_sock_fd, "r");
- char file_name[PATH_MAX];
- fscanf(handler_sock, "GET %s HTTP/1.1", file_name);
- int char1 = 0;
- int char2 = 0;
- int char3 = 0;
- int char4 = 0;
- while (!(char1 == (int)('\r') && char2 == (int)('\n') &&
- char3 == (int)('\r') && char4 == (int)('\n'))) {
- char1 = char2;
- char2 = char3;
- char3 = char4;
- char4 = fgetc(handler_sock);
- if (char4 == EOF) {
- break;
- }
- }
- send_answer(handler_sock_fd, file_name, argv[2]);
- shutdown(handler_sock_fd, SHUT_RDWR);
- fclose(handler_sock);
- }
- close(listen_sock_fd);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement