Skip to content

Commit

Permalink
some progress, need to split code, think about better way to pass dat…
Browse files Browse the repository at this point in the history
…a between functions and write logic for response
  • Loading branch information
robert72127 committed May 4, 2023
1 parent 5179726 commit 20ac5ef
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 12 deletions.
116 changes: 106 additions & 10 deletions webserver.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <netdb.h>
#include <sys/wait.h>
#include <signal.h>
#include <dirent.h>

#include "webserver.h"

Expand Down Expand Up @@ -60,9 +61,8 @@ int open_listenfd(char *port){
}


ssize_t serve (int fd)
{
struct timeval tv; tv.tv_sec = TIMEOUT; tv.tv_usec = 0;
ssize_t serve (int fd, int waittime, char **path){
struct timeval tv; tv.tv_sec = waittime; tv.tv_usec = 0;
size_t total_bytes_read = 0;

fd_set descriptors;
Expand All @@ -71,7 +71,6 @@ ssize_t serve (int fd)
while (total_bytes_read < BUFFER_SIZE) {
// printf("DEBUG: Current value of tv = %.3f\n", (double)tv.tv_sec + (double)tv.tv_usec / 1000000);


int ready = select(fd + 1, &descriptors, NULL, NULL, &tv);
if (ready < 0){
ERROR("select error");
Expand All @@ -83,29 +82,102 @@ ssize_t serve (int fd)
ssize_t bytes_read = recv(fd, buffer + total_bytes_read, BUFFER_SIZE - total_bytes_read, 0);
if (bytes_read < 0)
ERROR("recv error");
if (bytes_read == 0)
if (bytes_read == 0){
/* didnt read anything will close connection right aways*/
return 0;
}


for (int i = 0; i < bytes_read; i++) {
if (buffer[total_bytes_read + i] == SEPARATOR)
for (int i = 0; i < bytes_read-1; i++) {
if (buffer[total_bytes_read + i] == '\n' && buffer[total_bytes_read + i + 1] == '\n')
buffer[total_bytes_read + i + 1] = '\0';
break;
}

//printf("DEBUG: %ld bytes read\n", bytes_read);
total_bytes_read += bytes_read;

}
return parse_request(path);
/*
int end = (total_bytes_read < BUFFER_SIZE )? total_bytes_read: BUFFER_SIZE-1;
buffer[end] = '\0';
printf("%s\n",buffer);

// ok easy sending back
if (send(fd, "Hello, fucker!", 15, 0) == -1)
perror("send");
return 0;
*/
}
/*path is correct if it doesn't reach beyond current dir and it exists*/
int check_path(char *path){
int size = strlen(path);
/*could check recursively but assuming inclusion of ../ is malicious is better heursitsics*/
for(int i = 0; i < size -2; i++){
if (path[i] == '.' && path[i+1] == '.' && path[i+2] == '/')
return 0;
}
/* check if directory exists */
DIR* dir = opendir(path);
if(dir){
/* it exists*/
closedir(dir);
return 1;
}
else{
return 0;
}
}
/*need to think bit more on that*/
char move(char **str){
while(*str){
if(*str == '\n'){
*str++;
*str = str;
}
*str++;
}
}

/* parse and handle content of buffer*/
int parse_request(char **path){
char host[MAXLINE];

char *buff_ = buffer;

if (!sscanf(buff_,"GET %s HTTP/%f\n",*path)){
return 0;
}
// checking path
if(! check_path(*path)){
return 0;
}
move(&buff_);
if(!sscanf(buff_,"Host: %s\n", host)){
return 0;
}
if(strcmp("localhost", host) && strcmp("virbian", host) && strcmp("virtual-domain.example.com", host)){
return 0;
}
move(&buff_);
if(!sscanf(buff_,"Connection:close\n")){
return 1;
}
return 2;
}

/* write response to assoctiated fd*/
void respond(char *path){
sprintf("")


}

int main(int argc, char **argv) {
int listenfd, confd;
char path[MAXLINE];

struct sockaddr_storage clientaddr;

Expand All @@ -117,10 +189,22 @@ int main(int argc, char **argv) {
}
char *port = argv[1];
char *directory = argv[2];

/* check if directory exists */
DIR* dir = opendir(directory);
if(dir){
/* it exists*/
closedir(dir);
}
else{
fprintf(stderr, "Error directory does not exists.\n");
exit(0);
}

/* create listening descriptor */
listenfd = open_listenfd(port);
/* main loop */
bool keep_conv;
while(1){

/* file descriptor connected to client */
Expand All @@ -131,8 +215,20 @@ int main(int argc, char **argv) {
}

printf("Accepted connection on port : %s\n", port);

serve(confd);

keep_conv = serve(confd, WAITTIME, &path);
/* connection close was send */
if(keep_conv == 2){
respond(path);
continue;
}
/* wait for further requests */
while(keep_conv){
respond(path);

// and then wait for maybe more messages
serve(confd, WAITTIME, &path);
}

close(confd);

Expand Down
10 changes: 8 additions & 2 deletions webserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,11 @@
#define BUFFER_SIZE 10000000 // 10 MB
#define MAXLINE 80
#define BACKLOG 16 // how many pending connections to hold
#define SEPARATOR 'x'
#define TIMEOUT 10 // timeout of 10 seconds :O
#define TIMEOUT 10 // timeout of 10 seconds :O

/*stop parsing at double blank or error*/
struct request {
char resource[MAXLINE];
char host[MAXLINE];
char connection[MAXLINE];
};

0 comments on commit 20ac5ef

Please sign in to comment.