I am programming a very simple web server in C called tinyWeb
. And there is something wrong about it that i can't understand. I spent hours of time trying to find whats wrong. But I failed to find it.Also this program is running on special privileges. I think there is something wrong with the below function that I used to send information to the client host.
int send_string(int sockfd, unsigned char *buffer){
int sent_bytes, bytes_to_send;
bytes_to_send = strlen(buffer);
while(bytes_to_send > 0){
sent_bytes = send(sockfd, buffer, bytes_to_send, 0);
if(sent_bytes == -1);
return 0;
bytes_to_send -= sent_bytes;
buffer += sent_bytes;
}
printf("ALL BYTES SENT\n"); //I can't see this message.
return 1;
Here is the full source code.
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "XXX.h"
#define PORT 80
#define WEBROOT "./webroot" //serevers root
void handle_connection(int, struct sockaddr_in *); //handle web request
int get_file_size(int); //returns the file soze of open file descriptor
int main(void){
int sockfd, new_sockfd, yes=1;
struct sockaddr_in host_addr, client_addr;
socklen_t sin_size;
printf("Accepting web requests on port %d\n", PORT);
if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1){
printf("ERROR: while creating socket\n");
exit(0);
}
if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) ==-1){
printf("ERROR: while setting socket option SO_REUSEADDR\n");
exit(0);
}
host_addr.sin_family = AF_INET;
host_addr.sin_port = htons(PORT);
host_addr.sin_addr.s_addr = INADDR_ANY;
memset(&(host_addr.sin_zero), '\0', 8);
if(bind(sockfd, (struct sockaddr *)&host_addr, sizeof(struct sockaddr)) == -1){
printf("ERROR: while binding socket to address.\n");
exit(0);
}
if(listen(sockfd, 20) == -1){
printf("ERROR: while listening for connections\n");
exit(0);
}
while(1){
printf("in while(1)\n");
sin_size = sizeof(struct sockaddr_in);
printf("done up to sin_size\n");
new_sockfd = accept(sockfd, (struct sockaddr *)&client_addr, &sin_size);
printf("done up to accept\n");
if(new_sockfd == -1){
printf("ERROR: while accepting connection\n");
exit(0);
}
handle_connection(new_sockfd, &client_addr);
}
return 0;
}
void handle_connection(int sockfd, struct sockaddr_in *client_addr_ptr){
unsigned char *ptr, request[500], resourse[500];
int fd, len;
len = recv_line(sockfd, request); //scroll below to see this function.
printf("done up to recv_line()\n");
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/"); //search for HTTP
if(ptr == NULL){
printf("NOT HTTP!\n");
}
else{
*ptr = 0;
ptr = NULL;
printf("request is HTTP\n");
if(strcmp(request, "GET ")){
ptr = request+4;
printf("is a get request\n");
}
if(strcmp(request, "HEAD ")){
ptr = request+5;
printf("is a head request\n");
}
if(ptr == NULL){
printf("NULL: ");
printf("\tUNKNOWN REQUEST!\n");
}
else{
printf("%s\n", ptr);
if((ptr[strlen(ptr)-1]) == '/' )
strcat(ptr, "/index.html"); //add index.html to the end strcat().
strcpy(resourse, WEBROOT);
strcat(resourse, ptr);
fd = open(resourse, O_RDONLY, 0);
printf("opening file \'%s\' \n", resourse);
if (fd == -1){
printf(" 404 Not Found\n");
send_string(sockfd, "HTTP/1.0 404 Not Found\r\n");
send_string(sockfd, "Serever: Tiny webserver\r\n");
send_string(sockfd, "<html><head><title>404 Not Found</title></head>\r\n");
send_string(sockfd, "<body><h1>URL not found</h1></body></html>\r\n");
}
else{
printf("200 OK\n");
unsigned char temp_buffer[] = "HTTP/1.0 200 OK\r\n";
send(sockfd, &temp_buffer, strlen(temp_buffer), 0);
unsigned char temp2_buffer[] = "Server: Tiny webserver\r\n";
send(sockfd, &temp2_buffer, strlen(temp_buffer), 0);
printf("done sending basic info\n");
if((ptr == request+4) || (ptr == request+5)){ //if it's a GET request.
printf("ptr is request+4\n");
if((len=get_file_size(fd)) == -1){
printf("Error: while getting file size\n");
exit(0);
}
if((ptr = (unsigned char *)malloc(len)) == NULL){
printf("Error: while allocatin memory of heap\n");
exit(0);
}
printf("passed get_file_size() and malloc() succesfully\n");
read(fd, ptr, len);
send(sockfd, ptr, len, 0);
printf("file sent\n"); //I can see this massege on the terminal but the browser is not displaying any thing.
free(ptr);
}
close(fd);
}
}
}
}
int get_file_size(int fd){
struct stat fileInfo;
if(fstat(fd, &fileInfo) == -1)
return -1;
return (int) fileInfo.st_size;
}
Below is the content of XXX.h
file.
#define EOL "\r\n"
#define EOL_SIZE
//This is the previously mentioned send_string function.
int send_string(int sockfd, unsigned char *buffer){
int sent_bytes, bytes_to_send;
bytes_to_send = strlen(buffer);
while(bytes_to_send > 0){
sent_bytes = send(sockfd, buffer, bytes_to_send, 0);
if(sent_bytes == -1);
return 0;
bytes_to_send -= sent_bytes;
buffer += sent_bytes;
}
printf("ALL BYTES SENT\n"); //I can't see this message.
return 1;
}
int recv_line(int sockfd, unsigned char *dest_buffer){
printf("int recv_line()\n");
unsigned char *ptr;
int eol_match = 0;
ptr = dest_buffer;
printf("assigning to ptr done\n");
while(recv(sockfd, ptr, 1, 0) == 1){
printf(".");
if(*ptr == EOL[eol_match]){
eol_match++;
if(eol_match == EOL_SIZE){
*(ptr+1-EOL_SIZE) = '\0';
return strlen(dest_buffer);
}else{
eol_match == 0;
}
}
ptr++;
}
return 0;
}
When I start the server program and type my IP address on the browser it keep loading forever until I terminate the server program with ^c
and I can't figure out whats wrong. I will really appreciate your help.
Aucun commentaire:
Enregistrer un commentaire