diff options
| author | not-a-robot06 <72096472+not-a-robot06@users.noreply.github.com> | 2024-04-07 08:41:45 +0100 |
|---|---|---|
| committer | not-a-robot06 <72096472+not-a-robot06@users.noreply.github.com> | 2024-04-07 08:41:45 +0100 |
| commit | f52e10b10b9d39dabf6e057cd4ab6e980d97240b (patch) | |
| tree | 5187a867c42984b239528011f80a74e94768eb50 /http.c | |
| download | http-server-f52e10b10b9d39dabf6e057cd4ab6e980d97240b.tar.gz http-server-f52e10b10b9d39dabf6e057cd4ab6e980d97240b.tar.bz2 http-server-f52e10b10b9d39dabf6e057cd4ab6e980d97240b.zip | |
Diffstat (limited to 'http.c')
| -rw-r--r-- | http.c | 109 |
1 files changed, 109 insertions, 0 deletions
@@ -0,0 +1,109 @@ +#include <stdio.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> +#include <strings.h> + +#define BUF_LEN 512 +#define PATH_LEN 256 +#define PORT "3456" +#define BACKLOG 10 + +int +main(void){ + struct sockaddr_storage client_addr; + socklen_t addr_size = sizeof client_addr; + struct addrinfo hints, *serv_info; + int sockfd, acpt_fd, yes = 1, err, recv_len, file_len; + char buf[BUF_LEN], method[16], path[PATH_LEN], *file_buf; + FILE *file; + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; + hints.ai_flags = AI_PASSIVE; + hints.ai_socktype = SOCK_STREAM; + + if ((err = getaddrinfo(NULL, PORT, &hints, &serv_info)) != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(err)); + return 1; + } + if ((sockfd = socket(serv_info->ai_family, serv_info->ai_socktype, + serv_info->ai_protocol)) < 0) { + perror("socket"); + exit(1); + } + if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) < 0) { + perror("setsockopt"); + exit(1); + } + if (bind(sockfd, serv_info->ai_addr, serv_info->ai_addrlen) < 0) { + perror("bind"); + exit(1); + } + freeaddrinfo(serv_info); + + if (listen(sockfd, BACKLOG) < 0) { + perror("listen"); + exit(1); + } + + if ((acpt_fd = + accept(sockfd, (struct sockaddr *)&client_addr, &addr_size)) < 0) { + perror("accept"); + exit(1); + } + chdir("./resources"); // folder where all files to send are + + while (1) { + if ((recv_len = recv(acpt_fd, buf, BUF_LEN, 0)) < 0) { + perror("accept"); + exit(1); + } + buf[recv_len] = '\0'; + + printf("got request: %s\n", buf); + sscanf(buf, "%s %s", method, path+1); //+1 as first char needs to be . + printf("method: %s\n", method); + if (strcmp(method, "GET") == 0) { + printf("requested: %s\n\n", path+1); + if (path[1] == '\0') { + printf("got empty request\n"); + continue; + } + path[0] = '.'; + + if ((file = fopen(path, "r")) == NULL) { + printf("opening \"%s\" didn't work (file nonexistent?)\n\n", path); + continue; + } + fseek(file, 0, SEEK_END); + file_len = ftell(file); + rewind(file); + + file_buf = malloc(file_len); + fread(file_buf, file_len, 1, file); + fclose(file); + file_buf[file_len] = '\0'; + + if (send(acpt_fd, file_buf, file_len, 0) < 0) { + perror("send"); + exit(1); + } + + free(file_buf); + // prevent data leak by resetting path (a second, empty GET request will + // otherwise send previous file + path[0] = path[1] = '\0'; + } + else + printf("invalid method\n"); + } + close(acpt_fd); + close(sockfd); + + return 0; +} |
