cs-3516-assignment-1/server/socket_server.c

88 lines
2.5 KiB
C
Raw Normal View History

#include "socket_server.h"
2018-09-08 21:26:34 +00:00
#include "../common/http_types.h"
#include "../common/socket_helper.h"
#include <math.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
2018-09-08 21:26:34 +00:00
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
/**
* Gets the address info for the given port, such that the server will listen on 0.0.0.
*
* @param port The port to listen on.
* @param info A pointer to a location where getaddrinfo can store data.
*
* @return The result of getaddrinfo. See `man getaddrinfo` for details.
*/
static int build_addr_info(int port, struct addrinfo **info) {
struct addrinfo hints = {.ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM};
// Get the number of chars in the port
int port_length = floor(log10(port)) + 1;
char *port_string = malloc((port_length + 1) * sizeof(char));
sprintf(port_string, "%d", port);
int addr_status = getaddrinfo(NULL, port_string, &hints, info);
free(port_string);
return addr_status;
}
/**
* Setup the server's socket for listening.
*
* @param port The port to listen on.
*
* @return A server_info representing the result of setting up the socket.
*/
struct server_info setup(int port) {
struct server_info info = {.sock_fd = -1};
struct addrinfo *addr_info;
int addr_status = build_addr_info(port, &addr_info);
if (addr_status != 0) {
info.status = STATUS_ERROR;
return info;
}
info.sock_fd = socket(addr_info->ai_family, addr_info->ai_socktype, addr_info->ai_protocol);
if (info.sock_fd == -1) {
info.status = STATUS_ERROR;
return info;
}
int bind_result = bind(info.sock_fd, addr_info->ai_addr, addr_info->ai_addrlen);
if (bind_result == -1) {
close(info.sock_fd);
info.sock_fd = -1;
info.status = STATUS_ERROR;
return info;
}
2018-09-08 21:26:34 +00:00
int listen_result = listen(info.sock_fd, 8); if (listen_result == -1) {
close(info.sock_fd);
info.sock_fd = -1;
info.status = STATUS_ERROR;
return info;
}
info.status = STATUS_LISTENING;
return info;
}
2018-09-08 21:26:34 +00:00
enum socket_read_result serve_one_request(int sock_fd) {
int client_fd = accept(sock_fd, NULL, NULL);
if (client_fd == -1) {
return RESULT_WRITE_ERROR;
}
struct http_message message = {};
get_all_remote_parts(client_fd, TYPE_SERVER, &message);
printf("%s\n", message.contents);
char *msg = "HTTP/1.1 501 Not Imlemented Yet :(\r\n\r\n";
send(client_fd, msg, strlen(msg), 0);
shutdown(client_fd, SHUT_RDWR);
close(client_fd);
return RESULT_OK;
}