Giter Club home page Giter Club logo

webserv's Introduction

WEBSERVER C++ Python HTML5

Webserver is a 42 Wolfsburg curriculum project which is written using C++, Python for CGI scripts and HTML for basic webpages.

What is Webserver?

The project is about writing an HTTP server in C++ 98 and learning about the primary function of a web server, which is to store, process and serve webpages to to clients. Communication between client and server is done using the Hypertext Transfer Protocol (HTTP) --> listening to clients HTTP requests for files and returning them back to the client.
The web browser initiates communication by requesting a specific resource using HTTP, and the server responds with the content of that resource or an error message if it is unable to do so.

How does the Client acces the webserver?

Client can access the webserver using a localhost and the port that is specified by the webserver. For it to work the webserver first has to be running in the background.

How to run the webserver

  • Clone the repository git clone [email protected]:RanniSch/Webserv.git ./the_name_of_your_choice
  • cd into the repository cd the_name_of_your_choice
  • cd into the simplified-serv cd simplified-serv
  • Run the command make
  • Run webserver ./webserv [path of config file]
  • Open the browser and type in localhost:8000
  • You can test different scenarios by localhost:8000/[different scenarios] f.e. localhost:8000/upload.html

Prerequisites

  • The server is serving a fully static website
  • The GET, POST and DELETE methods are implemented.
  • Clients can upload files.
  • The HTTP response status codes are correct
  • The server has default error pages if none are provided
  • The server can listen on multiple ports
  • The server is compatible with the Firefox and Chrome web browsers.
  • The program takes a configuration file as an argument or uses a default path
  • The program is non-blocking and uses only 1 poll() (or equivalent) for all I/O operations between the client and the server (including listening).
  • poll() checks reads and writes at the same time
  • Every read or write goes through poll()
  • A request to the server will never hang forever
  • NGINX is HTTP 1.1 compliant

Configuration File

In the configuration file, you can

  • Choose the port and host of each 'server'.
  • Set the server_names or not
  • Set default error pages
  • Limit client body size
  • Set up routes with one or more rules/configurations

Various configuration files and default base files for testing and demonstrating each feature are provided.

webserv-1

webserv-2

webserv-3

webserv-4

webserv-5

webserv's People

Contributors

maxihme avatar lukaskava avatar rannisch avatar

Watchers

 avatar

Forkers

maxihme lukaskava

webserv's Issues

PROBLEM: Mandatory Part: Check the code and ask questions: Launch the installation of siege with homebrew.

siege http://localhost:8000/animal.jpg --> no failed transactions

siege http://localhost:8000/index.html --> segmentation fault
image

siege http://localhost:8000/upload.html --> Aborted
image


For Mac "brew install siege"

For Linux "sudo apt-get install siege"

How to use siege?
Start the server, open a second terminal and type in "siege http://example.com"
Stresstest: "siege -c 10 -t 1M http://example.com" --> -c 10 means that 10 users sending their request at the same time
-t 1M means that the tests should run for one Minute

What is siege?
Siege is a command line tool for load testing web servers and web applications. It sends a large number of parallel requests to the server to test its response to load situations. Siege allows you to test the responsiveness and performance of a server under stress by simulating a large number of requests.

What is homebrew?
Homebrew is a package manager for macOS operating systems. It enables the easy installation of open source software and tools by automating their installation, updating and uninstallation.

PROBLEM: Basic checks: Using telnet, curl, prepared files, demonstrate that the following features work properly: For every test you should receive the appropriate status code.

Is it enough to see the status code f.e. in Postman, or shall we print it also in the terminal?

Tested: localhost:8000/diversion.html --> shouldn't this give status code 301? It showed status code 200. Max: the requested html was loaded, that is a 200. And then the browser sees in that html a redirection and loads the page http://localhost:8000/upload.html (the redirection is in the html, and does not come from the server)

localhost:8000/upload.html worked and showed 200
localhost:8000/diversion.ht worked and showed 404

PROBLEM: Basic checks: Using telnet, curl, prepared files, demonstrate that the following features work properly: Upload some file to the server and get it back.

Tested with: http://localhost:8000/upload.html

Uploaded a jpg, png, gif, pdf, mp4 and prproj

Mp4 and prproj is returned as a download.

The PDF Subject gets printed on the screen, Terminal produces errors. Or is meant with error:0 that there is no error? Similar output with socket 11 for the mp4 data type. Max: I think it means that the error is 0, so nothing
image

Mandatory Part: Ask explanations about the basics of an HTTP server.

An HTTP server, short for Hypertext Transfer Protocol server, is a crucial component of the World Wide Web. It serves as the backbone for communication between clients (usually web browsers) and web servers. HTTP servers receive incoming requests from clients, process those requests, and deliver web content, such as HTML pages, images, or other resources, in response. They use the HTTP protocol to ensure the proper exchange of information between clients and servers.

Basic checks: UNKNOWN requests should not result in a crash.

PUT request with postman to 127.0.0.1:8000/ -> browser hangs and terminal is full of:
FILE WAS NOT BEEN OPEN! (tmp folder exists)

restart try again, same.
restart try again, same.
restart try again, same. -> seems to be consistent
when I click on Cancel in postman, new printing of FILE WAS NOT BEEN OPEN! stops
and after some time comes: "ERROR: recv has failed!
CHECK RECV ERROR: : Connection reset by peer"

i tryed with PATCH request, same behaviour

UPDATE 31.10:
with docker I get 501
on mac I get 501 (not implemented) (correct)
could you both test it @RanniSch @LukasKava

Ranja: For me it throws 404 error in postman, but no hanging.
In Browser it redirects to the index.html, but no hanging.

Mandatory Part: Ask for an explanation of how does select() (or equivalent) work.

select() is a system call that allows you to monitor multiple file descriptors, typically used for managing I/O operations on sockets. It works by creating sets of file descriptors you want to monitor using the fd_set data structure.

You set up three fd_set structures: one for the file descriptors you want to read from, one for those you want to write to, and one for exceptions. These sets are manipulated using functions like FD_SET(), FD_CLR(), and FD_ZERO() to add, remove, or clear file descriptors.

You pass these sets, along with a timeout value, to the select() function. select() will block until one or more file descriptors in the sets become ready, or until the timeout expires. Once select() returns, you can check which file descriptors are ready and perform the corresponding I/O operations without blocking the entire program.

PROBLEM: Guidelines: You must also verify the absence of memory leaks. Any memory allocated on the heap must be properly freed before the end of execution. You are allowed to use any of the different tools available on the computer, such as leaks, valgrind, or e_fence. In case of memory leaks, tick the appropriate flag.

Tested with: valgrind --leak-check=full --show-leak-kinds=all ./webserv

simple Test with: http://localhost:8000/cgi-bin/script-get-2.py (same results with other tests)

LEAK SUMMARY:
==4819== definitely lost: 0 bytes in 0 blocks
==4819== indirectly lost: 0 bytes in 0 blocks
==4819== possibly lost: 0 bytes in 0 blocks
==4819== still reachable: 24,759 bytes in 377 blocks
==4819== suppressed: 0 bytes in 0 blocks
==4819==
==4819== For lists of detected and suppressed errors, rerun with: -s
==4819== ERROR SUMMARY: 3 errors from 2 contexts (suppressed: 0 from 0)

Problem: Terminal does not show the first error anymore. It looks like that the leaks (or some of them) are in the Config Class. Maybe in a vector there.

Configuration: Setup default error page (try to change the error 404).

functionality works but when I change the config and restart, gives segfault.

tried with http://localhost:8000/cgi-bi.gh comes 404 - works as expected

change config to:
server
{
error404 error/error500.html;
}

and with the same url error 500 comes - works as expected

BUT SEGFAULT:
"READING AND PARSING! [NOTHING]
TMP_METHOD: [GET]
CHOSEN METHOD: [GET]
PREPARING RESPONSE 1
PREPARING RESPONSE 2
CRAFTED GET RESPONSE STR
ACCEPT CONNECTION => 3DONE

WE HAVE FINISHED WRITING TO THE BROWSER
Client Socket: 6 was closed successfuly
File deleted successfully: tmp/tmp_file_6
make: *** [e] Segmentation fault: 11
mbp:simplified-serv maxrehberg$ "

tried again, no segfault. And then server was still running, klick on reload. Now hangs forever but gets every second a new PID -> new process???

restarted webserve. error 500 comes as expected. I can reload the page 4 times and all works.

change config to:
server
{
#error404 error/error404.html;
}

default error page will be shown as expected. but again a segfault:
"mbp:simplified-serv maxrehberg$ make e
./webserv conf/webserve_.conf
Information: cannot open your config file. Will take default Config.
TestServer constructor called!
Start Listening...
Start Listening...
Start Listening...
Finished creating the ports:
Listening Socket onject for Port: 8000fd: 3 succesfully created!
Listening Socket onject for Port: 8080fd: 4 succesfully created!
Listening Socket onject for Port: 8090fd: 5 succesfully created!
ERROR: poll() has timed out: : No such file or directory
ACCEPT CONNECTION => 3DONE

READING AND PARSING! [NOTHING]
TMP_METHOD: [GET]
CHOSEN METHOD: [GET]
PREPARING RESPONSE 1
PREPARING RESPONSE 2
CRAFTED GET RESPONSE STR
ACCEPT CONNECTION => 3DONE

WE HAVE FINISHED WRITING TO THE BROWSER
Client Socket: 6 was closed successfuly
File deleted successfully: tmp/tmp_file_6
make: *** [e] Segmentation fault: 11
mbp:simplified-serv maxrehberg$ "

restart webserve. everything works. can load the page several times, all good.

change the config again to:

server
{
error404 error/error500.html;
}
-> error page correct in the browser, and again segfault:

"mbp:simplified-serv maxrehberg$ make e
./webserv conf/webserve_.conf
Information: cannot open your config file. Will take default Config.
TestServer constructor called!
Start Listening...
Start Listening...
Start Listening...
Finished creating the ports:
Listening Socket onject for Port: 8000fd: 3 succesfully created!
Listening Socket onject for Port: 8080fd: 4 succesfully created!
Listening Socket onject for Port: 8090fd: 5 succesfully created!
ERROR: poll() has timed out: : No such file or directory
ACCEPT CONNECTION => 3DONE

READING AND PARSING! [NOTHING]
TMP_METHOD: [GET]
CHOSEN METHOD: [GET]
PREPARING RESPONSE 1
PREPARING RESPONSE 2
CRAFTED GET RESPONSE STR
ACCEPT CONNECTION => 3DONE

WE HAVE FINISHED WRITING TO THE BROWSER
Client Socket: 6 was closed successfuly
File deleted successfully: tmp/tmp_file_6
make: *** [e] Segmentation fault: 11
mbp:simplified-serv maxrehberg$ "

SEGFAULT when changing the config

tried with http://localhost:8000/cgi-bi.gh comes 404 - works as expected

change config to:
server
{
error404 error/error500.html;
}

and with the same url error 500 comes - works as expected

BUT SEGFAULT:
"READING AND PARSING! [NOTHING]
TMP_METHOD: [GET]
CHOSEN METHOD: [GET]
PREPARING RESPONSE 1
PREPARING RESPONSE 2
CRAFTED GET RESPONSE STR
ACCEPT CONNECTION => 3DONE

WE HAVE FINISHED WRITING TO THE BROWSER
Client Socket: 6 was closed successfuly
File deleted successfully: tmp/tmp_file_6
make: *** [e] Segmentation fault: 11
mbp:simplified-serv maxrehberg$ "

tried again, no segfault. And then server was still running, klick on reload. Now hangs forever but gets every second a new PID -> new process???

restarted webserve. error 500 comes as expected. I can reload the page 4 times and all works.

change config to:
server
{
#error404 error/error404.html;
}

default error page will be shown as expected. but again a segfault:
"mbp:simplified-serv maxrehberg$ make e
./webserv conf/webserve_.conf
Information: cannot open your config file. Will take default Config.
TestServer constructor called!
Start Listening...
Start Listening...
Start Listening...
Finished creating the ports:
Listening Socket onject for Port: 8000fd: 3 succesfully created!
Listening Socket onject for Port: 8080fd: 4 succesfully created!
Listening Socket onject for Port: 8090fd: 5 succesfully created!
ERROR: poll() has timed out: : No such file or directory
ACCEPT CONNECTION => 3DONE

READING AND PARSING! [NOTHING]
TMP_METHOD: [GET]
CHOSEN METHOD: [GET]
PREPARING RESPONSE 1
PREPARING RESPONSE 2
CRAFTED GET RESPONSE STR
ACCEPT CONNECTION => 3DONE

WE HAVE FINISHED WRITING TO THE BROWSER
Client Socket: 6 was closed successfuly
File deleted successfully: tmp/tmp_file_6
make: *** [e] Segmentation fault: 11
mbp:simplified-serv maxrehberg$ "

restart webserve. everything works. can load the page several times, all good.

change the config again to:

server
{
error404 error/error500.html;
}
-> error page correct in the browser, and again segfault:

"mbp:simplified-serv maxrehberg$ make e
./webserv conf/webserve_.conf
Information: cannot open your config file. Will take default Config.
TestServer constructor called!
Start Listening...
Start Listening...
Start Listening...
Finished creating the ports:
Listening Socket onject for Port: 8000fd: 3 succesfully created!
Listening Socket onject for Port: 8080fd: 4 succesfully created!
Listening Socket onject for Port: 8090fd: 5 succesfully created!
ERROR: poll() has timed out: : No such file or directory
ACCEPT CONNECTION => 3DONE

READING AND PARSING! [NOTHING]
TMP_METHOD: [GET]
CHOSEN METHOD: [GET]
PREPARING RESPONSE 1
PREPARING RESPONSE 2
CRAFTED GET RESPONSE STR
ACCEPT CONNECTION => 3DONE

WE HAVE FINISHED WRITING TO THE BROWSER
Client Socket: 6 was closed successfuly
File deleted successfully: tmp/tmp_file_6
make: *** [e] Segmentation fault: 11
mbp:simplified-serv maxrehberg$ "

Check CGI: You need to test with files containing errors to see if the error handling works properly. You can use a script containing an infinite loop or an error; you are free to do whatever tests you want within the limits of acceptability that remain at your discretion. The group being evaluated should help you with this. The server should never crash and an error should be visible in case of a problem.

Tested with:
http://localhost:8000/cgi-bin/script-infinite-loop.py

Only tested with a script that contains an infinite loop, not an error.

Port Issues: Launch multiple servers at the same time with different configurations but with common ports. Does it work? If it does, ask why the server should work if one of the configurations isn't functional. Keep going.

started webserve from 2 different terminals. The second one says: (looks good for me)

"mbp:simplified-serv maxrehberg$ make e
./webserv conf/webserve.conf
Information: cannot open your config file. Will take default Config.
TestServer constructor called!
Start Listening...
bind failed... : Address already in use
make: *** [e] Error 1"

Check with a browser: Try to list a directory.

The browser does not list the content of a directory.

Tested with: localhost:8000/www

Max:
our root directory is www/
config:
...
root /www;
...

thats why when you want: localhost:8000/www it want's you to give ...webserve/simplified-serv/www/www and not ...webserve/simplified-serv/www/

to list www/ you have to turn autoindex on; and no index argument for that location. location / means in browser localhost:8000/ and locally ...webserve/simplified-serv/www/
config:
location /
{
allowed_Methods GET POST;
#index index.html;
autoindex on;
}
then go to localhost:8000/ in browser

Download 3,9GB Data from the server

limit the downloadabe filesize to 500 MB. Update: is done returns 413, Payload to large
http://localhost:8000/debia.iso

it's some time at "preparing response"
Bildschirmfoto 2023-11-01 um 13 01 35

and the memory of webserve goes up and down (up to 12 GB in Ram)
Bildschirmfoto 2023-11-01 um 13 01 44

when the download is starting the server says 408 takes to long and in the browser the download is aborted
Bildschirmfoto 2023-11-01 um 13 01 57

Configuration: Setup multiple servers with different ports.

EDIT: No Problem anymore

config:
server
{
listen 8000 8080 8010;
...
}
server
{
listen 8090 ;
....
}

open http://localhost:8000/ -> works fine
open http://localhost:8090/ -> throws either bad alloc or segfault: (I tested several times, and it seems to work with different servers with different ports, the errors happen occasionally)

"HEADER: GET / HTTP/1.1
Host: localhost:8090
Connection: keep-alive
sec-ch-ua: "Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
NOTHING 0
ACCEPT CONNECTION => 8DONE

WRITING back to the socket: 9 fd: 9 error:0
WE HAVE FINISHED WRITING TO THE BROWSER
Client Socket: 9 was closed successfuly
File deleted successfully: tmp/tmp_file_9
make: *** [Makefile:85: e] Segmentation fault
➜ simplified-serv git:(main) ✗ "

and another time this message comes:

"WRITING back to the socket: 10 fd: 10 error:0
WRITING back to the socket: 10 fd: 10 error:0
WE HAVE FINISHED WRITING TO THE BROWSER
Client Socket: 10 was closed successfuly
File deleted successfully: tmp/tmp_file_10
ACCEPT CONNECTION => 8DONE

ACCEPT CONNECTION => 6DONE

terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
make: *** [Makefile:85: e] Aborted
➜ simplified-serv git:(test_dienstag) ✗ "

Configuration: Setup routes in a server to different directories.

the function seems all good, but the server has problems.

config:
location /
{
index index.html;
allowed_Methods POST;
}

location /delete_dir
{
	allow_methods DELETE;
}

location /static_website
{
	allow_methods GET;
	index static.html;
}

http://localhost:8000/ -> error page 405 method not allowed -> correct

but Segfault:
"Listening Socket onject for Port: 8090fd: 5 succesfully created!
ERROR: poll() has timed out: : No such file or directory
ACCEPT CONNECTION => 3DONE

READING AND PARSING! [NOTHING]
TMP_METHOD: [GET]
CHOSEN METHOD: [GET]
PREPARING RESPONSE 1
PREPARING RESPONSE 2
CRAFTED GET RESPONSE STR
ACCEPT CONNECTION => 3DONE

WE HAVE FINISHED WRITING TO THE BROWSER
Client Socket: 6 was closed successfuly
File deleted successfully: tmp/tmp_file_6
make: *** [e] Segmentation fault: 11
mbp:simplified-serv maxrehberg$ "

restart try again, same segfault. restart try again, same segfault.

try: http://localhost:8000/static_website/
page loaded, pictures not, same segfault
restart try again, same segfault.

restart try again, all good, i can reload the page.
restart, browser hangs. debugging says it hangs at "int TestServer::checkPollAction(short revents, int fd)" second if (like in the screenshot).

Siege & stress test: You should be able to use siege indefinitely without having to restart the server (take a look at siege -b).

I ran the following without restarting the server:

siege -c 10 -t 1M http://localhost:8000/animal.jpg --> perfect

siege -c 10 -t 1M http://localhost:8000/upload.html --> perfect

siege -c 10 -t 1M http://localhost:8000/index.html --> perfect

siege -c 10 -t 1M http://localhost:8000/cgi-bin/script-post-2.py --> perfect

siege -b http://localhost:8000/listing_Kopie.html
when I run it short --> perfect
when I run it super long
image

With 27 transactions failed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.