dimanche 3 octobre 2021

Request to this serever keep loading forever

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