Created
April 20, 2013 04:55
-
-
Save shonenada/5424807 to your computer and use it in GitHub Desktop.
A simple http server in C
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <arpa/inet.h> | |
#include <fcntl.h> | |
#define WEBROOT "./webroot" // the web server's root directory | |
#define PORT = 8080; | |
void handle_connection(int, struct sockaddr_in*); | |
int get_file_size(int); | |
int main() | |
{ | |
int sockfd, clientfd; | |
socklen_t cliaddr_len; | |
struct sockaddr_in server_addr, client_addr; | |
sockfd = socket(AF_INET, SOCK_STREAM, 0); | |
if(sockfd == -1) | |
{ | |
printf("Error!"); | |
exit(1); | |
} | |
bzero(&server_addr, sizeof(server_addr)); | |
server_addr.sin_family = AF_INET; | |
server_addr.sin_port = htons(PORT); | |
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); | |
int br = bind(sockfd, (struct sockaddr *) &server_addr, sizeof(server_addr)); | |
if(br == -1) | |
{ | |
printf("Error!"); | |
exit(1); | |
} | |
if((listen(sockfd, 20)) == -1) | |
{ | |
printf("Error"); | |
exit(1); | |
} | |
while(1) | |
{ | |
clientfd = accept(sockfd, (struct sockaddr *) &client_addr, &cliaddr_len); | |
if(clientfd == -1) | |
{ | |
printf("waiting for connection."); | |
} | |
handle_connection(clientfd, &client_addr); | |
} | |
return 1; | |
} | |
void handle_connection(int sockfd, struct sockaddr_in *client_addr_ptr) | |
{ | |
unsigned char *ptr, request[500], resource[500]; | |
int fd, length; | |
length = recv(sockfd, request, 500, 0); | |
printf("Got request from %s:%d \"%s\"\n", inet_ntoa(client_addr_ptr->sin_addr), ntohs(client_addr_ptr->sin_port), request); | |
ptr = strstr(request, " HTTP/"); | |
if(ptr == NULL) | |
{ | |
printf(" NOT HTTP!\n"); | |
} else { | |
*ptr = 0; | |
ptr = NULL; | |
if(strncmp(request, "GET ", 4) == 0) | |
ptr = request + 4; | |
if(strncmp(request, "HEAD ", 5) == 0) | |
ptr = request + 5; | |
if(ptr == NULL) { | |
printf("\tUNKNOWN REQUEST!\n"); | |
} else { | |
if (ptr[strlen(ptr) - 1] == '/') | |
strcat(ptr, "index.html"); | |
strcpy(resource, WEBROOT); | |
strcat(resource, ptr); | |
fd = open(resource, O_RDONLY, 0); | |
printf("\tOpening \'%s\'\t", resource); | |
if(fd == -1) { | |
printf(" 404 Not Found\n"); | |
send(sockfd, "HTTP/1.0 404 NOT FOUND\r\n", 24, 0); | |
} else { | |
printf(" 200 OK\n"); | |
send(sockfd, "HTTP/1.0 200 OK\r\n", 17, 0); | |
send(sockfd, "Server: C\r\n\r\n", 13, 0); | |
if(ptr == request + 4) { | |
if( (length = get_file_size(fd)) == -1) | |
{ | |
printf("getting resource file size"); | |
exit(1); | |
} | |
if( (ptr = (unsigned char *) malloc(length)) == NULL) | |
{ | |
printf("allocating memory for reading resource"); | |
exit(1); | |
} | |
read(fd, ptr, length); | |
send(sockfd, ptr, length, 0) | |
free(ptr); | |
} | |
close(fd); | |
} | |
} | |
} | |
shutdown(sockfd, SHUT_RDWR); | |
} | |
int get_file_size(int fd) { | |
struct stat stat_struct; | |
if(fstat(fd, &stat_struct) == -1) | |
return -1; | |
return (int) stat_struct.st_size; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment