//**************************************************************** //** ** //** PHilip RUshik. 2010,2011,2012,2013 ** //** Distributed under the terms of the Beerware License ** //** Philip Rushik wrote this code. As long as you retain ** //** this notice, you can do whatever you want with this ** //** stuff. If we meet someday, and you think this stuff ** //** is worth it, you can buy me a beer in return. ** //** --Philip Rushik ** //** ** //** HTTP Server ** //** ** //** Serves files via the HTTP 1.0 protocol. ** //** ** //**************************************************************** #include #include #include #include #include #include struct http_request { unsigned char * METHOD, * URI; float VERSION; }; struct http_status { float VERSION; unsigned short int CODE; unsigned char * REASON; }; struct http_body { unsigned int LENGTH; unsigned char * DATA; }; void error(unsigned char *msg) { perror(msg); exit(1); return; } struct http_request * parse_http_request(unsigned char *packet) { //HTTP REQUEST FORMAT // // // = GET POST HEAD // = Path to resource // = HTTP/x.xx struct http_request *request; request = malloc(sizeof(struct http_request)); int i=0; char j; do j=packet[i++]; while (j!=' ' && j!='\0'); request->METHOD=malloc(i); do j=packet[i++]; while (j!=' ' && j!='\0'); request->URI=malloc(i); int k = sscanf(packet,"%s %s HTTP/%f",request->METHOD,request->URI,&request->VERSION); return request; } //This function blindly sends an entire file. It does not check the file size void send_http_file(int sock, int bsize, unsigned char * fname) { unsigned char data[bsize]; int i; FILE *fd; fd = fopen(fname,"rb"); if (!fd) error("Error opening file"); write(sock,"HTTP/1.0 200 OK\r\n\r\n",19); i=fread(data,1,bsize,fd); write(sock,data,i); while (i==bsize) { i=fread(data,1,bsize,fd); write(sock,data,i); } return; } int main(int argc, unsigned char *argv[]) { printf("HTTP Server v0.1\nWritten by PHilip RUshik\n\n"); int sockfd, clilen, openfd; unsigned char buffer[512], *data; //How big should the buffer be? struct sockaddr_in serv_addr, cli_addr; int n; sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("Error opening socket"); memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(80); //HTTP uses port 80 if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) error("Error binding"); clilen = sizeof(cli_addr); while (1) { listen(sockfd,5); openfd = accept(sockfd,(struct sockaddr *) &cli_addr,&clilen); if (openfd < 0) error("Error accepting connection"); memset(&buffer, 0, 512); n = read(openfd,buffer,512); if (n <= 0) error("Error receiving"); struct http_request * test; test = parse_http_request(buffer); send_http_file(openfd,1024000,test->URI); close(openfd); } return 0; }