#include #include #include #include #include #include #include #include "server.h" int send_response(int fd, char *header, char *content_type, void *body, int content_length) { const int max_response_size = 65536; char response[max_response_size]; time_t current = time(NULL); char date_time[30]; strftime(date_time, sizeof(date_time), "%a, %d %b %Y %H:%M:%S %Z", localtime(¤t)); int header_length = sprintf(response, "%s\n" "Server: %s\n" "Date: %s\n" "Connection: close\n" "Content-Length: %d\n" "Content-Type: %s\n" "\n", header, SERVER_VERSION, date_time, content_length, content_type); printf("%s\n", (char *)body); //printf("%p\n", (char *)response); //printf("%p\n", &header_length); //printf("%p\n", (void *)(response + header_length)); memcpy(response + header_length, body, content_length); printf("%s\n", response); int write_res = write(fd, response, header_length + content_length); if (write_res < 0) { perror("webserver (write)"); return write_res; } return write_res; } int main() { char buffer[BUFFER_SIZE]; // char resp[] = "HTTP/1.0 200 OK\r\n" // "Server: webserver-c\r\n" // "Content-type: text/html\r\n\r\n" // "hello, world\r\n"; // create a socket int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { perror("webserver (socket)"); return 1; } printf("socket created successfully\n"); // create the address to bind the socket to struct sockaddr_in host_addr; int host_addrlen = sizeof(host_addr); host_addr.sin_family = AF_INET; host_addr.sin_port = htons(PORT); host_addr.sin_addr.s_addr = htonl(INADDR_ANY); // create client address struct sockaddr_in client_addr; int client_addrlen = sizeof(client_addr); // Bind the socket to the address if (bind(sockfd, (struct sockaddr *) &host_addr, host_addrlen) != 0) { perror("webserver (bind)"); return 1; } printf("socket successfully bound to address\n"); // listen to incoming connections if (listen(sockfd, SOMAXCONN) != 0) { perror("webserver (listen)"); return 1; } printf("server listening for connections\n"); for (;;) { // accept incoming connections int newsockfd = accept(sockfd, (struct sockaddr *) &host_addr, (socklen_t *) &host_addrlen); if (newsockfd < 0) { perror("webserver (accept)"); continue; } printf("connection accepted\n"); // get client address int sockn = getsockname(newsockfd, (struct sockaddr *) &client_addr, (socklen_t *) &client_addrlen); if(sockn < 0) { perror("webserver (getsockname)"); continue; } // read from the socket int valread = read(newsockfd, buffer, BUFFER_SIZE); if (valread < 0) { perror("webserver (read)"); continue; } // read the request char method[BUFFER_SIZE], uri[BUFFER_SIZE], version[BUFFER_SIZE]; sscanf(buffer, "%s %s %s", method, uri, version); printf("[%s:%u] %s %s %s\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), method, version, uri); // check if request is GET request if (strncmp("GET", method, 7) != 0) { // const char resp[] = "HTTP/1.0 400 Bad Request\r\n" // "Server: webserver-c\r\n" // "Content-Type: text/html\r\n\r\n"; char resp[100]; int resp_size = snprintf(resp, 100, "%s\r\n" "Server: %s\r\n" "Content-Type: %s\r\n" "\r\n", BAD_REQUEST_HEAD, SERVER_VERSION, "text/html"); int valwrite = write(newsockfd, resp, resp_size); if (valwrite < 0) { perror("webserver (write)"); continue; } } else { // char resp[100]; // int resp_size = snprintf(resp, 100, // "%s\r\n" // "Server: %s\r\n" // "Content-Type: %s\r\n" // "\r\n", // OK_HEAD, SERVER_VERSION, "text/html"); // // int valwrite = write(newsockfd, resp, resp_size); // printf("%s\n", OK_HEAD); // if (valwrite < 0) { // perror("webserver (write)"); // continue; // } char body[100]; int body_size = snprintf(body, 100, "%s\r\n", "hello what up bruh"); printf("%d\n", body_size); send_response(newsockfd, "HTTP/1.1 200 OK", "text/html", body, (body_size+1)); } // write to the socket // int valwrite = write(newsockfd, resp, strlen(resp)); // if (valwrite < 0) { // perror("webserver (write)"); // continue; // } close(newsockfd); } return 0; }