-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from san-ghun/config/repo_structure
Config/repo structure
- Loading branch information
Showing
9 changed files
with
255 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,109 @@ | ||
# webserv | ||
|
||
#### Summary | ||
|
||
This project is about writing a HTTP server in `C++ 98`. The server should be testable with actual browsers and others, like `wget` and `curl`. This project is aimed to learn about HTTP, one of the most used protocols on the internet, and implement compatible program with the protocol. | ||
|
||
## Introduction | ||
|
||
The **Hypertext Transfer Protocol** (HTTP) is an application protocol for distributed, collaborative, hypermedia information systems. | ||
|
||
HTTP is the foundation of data communication for the Wolrd Wide Web, where hypertext documents include hyperlinks to other resources that the user can easily access. For example, by a mouse click or by tapping the screen in a web browser. | ||
|
||
HTTP was developed to facilitate hypertext and the World Wide Web. | ||
|
||
The primary function of a web server is to store, process, and deliver web pages to clients. The communication between client and server takes place using the Hypertext Transfer Protocol (HTTP). | ||
|
||
Pages delivered are most frequently HTML documents, which may include images, style sheets, and scripts in addition to the text content. | ||
|
||
Multiple web servers may be used for a high-traffic website. | ||
|
||
A user agent, commonly a web browser or web crawler, initiates communication by requesting a specific resource using HTTP and the server responses with the content of that resource or an error message if unable to do so. The resource is typically a real file on the server's secondary storage, but this is not necessarily the case and depends on how the webserver is implemented. | ||
|
||
While the primary function is to serve content, full implementation of HTTP also includes ways of receiving content from clients. This feature is used for submitting web forms, including the uploading of files. | ||
|
||
--- | ||
|
||
## General rules | ||
|
||
- The program shoudl not crash in any circumstances, and should not quit unexpectedly. | ||
- even when it runs out of memory. | ||
- Use `Makefile` to compile all source files. | ||
- at least contain following rules: | ||
- `$(NAME)`, `all`, `clean`, `fclean` and `re`. | ||
- Use `c++` to compile code and flags with `-Wall -Wextra -Werror` | ||
- Code must comply with **C++ 98 standard**. It should still compile flag with `-std=c++98` | ||
- Try to develop using the most `C++` features. For example, choose `<cstring>` over `<string.h>`. | ||
- Any external library and `Boost` libraries are forbidden. | ||
|
||
--- | ||
|
||
## Goals | ||
|
||
- Implement a HTTP webserver comply with `HTTP/1.1`. | ||
- Implement the server to communicate in methods with GET, HEAD, DELETE, POST. | ||
- Implement a server that config with dedicated configuration file which is similar with how the **NGINX** do. | ||
- Support multi-port and routing. | ||
- Be able to serve full static webpage. | ||
- Use socket programming, asynchronous communication, non-block I/O | ||
- ...? | ||
|
||
--- | ||
|
||
## Features (ing) | ||
|
||
### Mandatory (ing) | ||
|
||
- Multi-port & Multi-host | ||
- IO Multiplex | ||
- Implement using `select()` or `poll()` or any equivalent. | ||
- ... | ||
|
||
### Configuration (ing) | ||
|
||
- Support Multi-port & Multi-host | ||
- Have default error pages | ||
- Able to limit the client body | ||
- Able to config root dir to serve | ||
- Able to config default file to serve | ||
- Able to authorize http method to specific route | ||
|
||
### Basic (ing) | ||
|
||
- Support GET POST DELETE methods based on HTTP/1.1 | ||
- Able to upload and download a file. | ||
|
||
### for Browser (ing) | ||
|
||
- Able to communicate with dedicated browsers | ||
- Firefox | ||
- Chrome | ||
- wget | ||
- curl | ||
- etc. | ||
- Check the pair of request header and reponse header respond as a pair | ||
- Able to serve full static website | ||
- html | ||
- css | ||
- js | ||
- Redirection(?) | ||
|
||
### Test (ing) | ||
|
||
- Use [siege](https://github.com/JoeDog/siege) or [plow](https://github.com/six-ddc/plow) to conduct load test | ||
- Check whether connections are maintained normally and nothing is terminated | ||
- Not allow auto-restart of the server | ||
- Minimize increase of mem-usage over an idle status | ||
- Check mem-leak | ||
|
||
## Coding Convention (ing) | ||
|
||
- Comment & documentation with `///` | ||
- Class | ||
- Naming private attribute with `_` | ||
- ex. `_somename = "abc";` | ||
- Utilize standard libraries as much as possible | ||
- std::map | ||
- std::vector | ||
- std::set | ||
- etc. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
This is a sample text file. |
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
http { | ||
types { | ||
text/css css; | ||
text/html html; | ||
} | ||
|
||
server { | ||
listen 8080; | ||
root ./static; | ||
|
||
location /fruits { | ||
root ./static; | ||
} | ||
|
||
location /obst { | ||
alias ./static/fruits; | ||
} | ||
|
||
location /vegetables { | ||
root ./static; | ||
try_files /vegetables/veggies.html /index.html =404; | ||
} | ||
} | ||
} | ||
|
||
events {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,7 @@ | |
/* By: sanghupa <[email protected]> +#+ +:+ +#+ */ | ||
/* +#+#+#+#+#+ +#+ */ | ||
/* Created: 2024/06/22 21:05:14 by sanghupa #+# #+# */ | ||
/* Updated: 2024/06/23 16:33:22 by sanghupa ### ########.fr */ | ||
/* Updated: 2024/06/23 22:47:25 by sanghupa ### ########.fr */ | ||
/* */ | ||
/* ************************************************************************** */ | ||
|
||
|
@@ -20,15 +20,11 @@ void run_server(int port); | |
void acceptNewConnections(int listen_sock, std::vector<pollfd>& fds); | ||
void handleClientData(int client_sock, std::vector<pollfd>& fds, size_t idx); | ||
|
||
/** | ||
* @brief Set a file descriptor to non-blocking mode. | ||
* | ||
* @param fd The file descriptor. | ||
* @return The result of the operation. 0 on success, -1 on failure. | ||
* | ||
* This function sets the file descriptor to non-blocking mode, allowing | ||
* for asynchronous I/O operations. | ||
*/ | ||
/// @brief Set a file descriptor to non-blocking mode. | ||
/// @param fd The file descriptor. | ||
/// @return The result of the operation. 0 on success, -1 on failure. | ||
/// This function sets the file descriptor to non-blocking mode, allowing | ||
/// for asynchronous I/O operations. | ||
int set_nonblocking(int fd) | ||
{ | ||
// Get the current file descriptor flags | ||
|
@@ -44,15 +40,11 @@ int set_nonblocking(int fd) | |
return fcntl(fd, F_SETFL, flags); | ||
} | ||
|
||
/** | ||
* @brief Create and bind a socket to a specific port. | ||
* | ||
* @param port The port number to bind the socket to. | ||
* @return The socket file descriptor on success, -1 on failure. | ||
* | ||
* This function creates a socket, sets the SO_REUSEADDR option, | ||
* binds the socket to the specified port, and makes the socket non-blocking. | ||
*/ | ||
/// @brief Create and bind a socket to a specific port. | ||
/// @param port The port number to bind the socket to. | ||
/// @return The socket file descriptor on success, -1 on failure. | ||
/// This function creates a socket, sets the SO_REUSEADDR option, | ||
/// binds the socket to the specified port, and makes the socket non-blocking. | ||
int create_and_bind(int port) | ||
{ | ||
int listen_sock; | ||
|
@@ -108,14 +100,10 @@ int create_and_bind(int port) | |
} | ||
|
||
|
||
/** | ||
* Parses an HTTP request and handles it. | ||
* | ||
* @param request The HTTP request to parse and handle. | ||
* @return The HTTP response to send back to the client. | ||
* | ||
* @throws None | ||
*/ | ||
/// @brief Parses an HTTP request and handles it. | ||
/// @param request The HTTP request to parse and handle. | ||
/// @return The HTTP response to send back to the client. | ||
/// @throws None | ||
std::string handle_request(const std::string& request) | ||
{ | ||
// Parse the HTTP request | ||
|
@@ -140,14 +128,10 @@ std::string handle_request(const std::string& request) | |
} | ||
|
||
|
||
/** | ||
* @brief Handle GET request by reading the file and returning an HTTP response. | ||
* | ||
* @param path The path of the file to read. | ||
* @return The HTTP response containing the file contents. | ||
* | ||
* In case the file is not found, a 404 Not Found response is returned. | ||
*/ | ||
/// @brief Handle GET request by reading the file and returning an HTTP response. | ||
/// @param path The path of the file to read. | ||
/// @return The HTTP response containing the file contents. | ||
/// In case the file is not found, a 404 Not Found response is returned. | ||
std::string handle_get(const std::string& path) | ||
{ | ||
// Prepend the current directory to the file path | ||
|
@@ -177,10 +161,8 @@ std::string handle_get(const std::string& path) | |
} | ||
|
||
|
||
/** | ||
* Main server loop that listens for incoming connections and handles requests. | ||
* @param port The port number to listen on. | ||
*/ | ||
/// @brief server loop that listens for incoming connections and handles requests. | ||
/// @param port The port number to listen on. | ||
void run_server(int port) | ||
{ | ||
int listen_sock = create_and_bind(port); | ||
|
@@ -226,11 +208,9 @@ void run_server(int port) | |
} | ||
} | ||
|
||
/** | ||
* Accepts new incoming connections and adds them to the list of file descriptors. | ||
* @param listen_sock The listening socket. | ||
* @param fds The vector of file descriptors. | ||
*/ | ||
/// @brief Accepts new incoming connections and adds them to the list of file descriptors. | ||
/// @param listen_sock The listening socket. | ||
/// @param fds The vector of file descriptors. | ||
void acceptNewConnections(int listen_sock, std::vector<pollfd>& fds) | ||
{ | ||
while (true) | ||
|
@@ -254,12 +234,10 @@ void acceptNewConnections(int listen_sock, std::vector<pollfd>& fds) | |
} | ||
} | ||
|
||
/** | ||
* Handles the data received from a client. | ||
* @param client_sock The socket of the client. | ||
* @param fds The vector of file descriptors. | ||
* @param idx The index of the client socket in the vector. | ||
*/ | ||
/// @brief the data received from a client. | ||
/// @param client_sock The socket of the client. | ||
/// @param fds The vector of file descriptors. | ||
/// @param idx The index of the client socket in the vector. | ||
void handleClientData(int client_sock, std::vector<pollfd>& fds, size_t idx) | ||
{ | ||
char buffer[BUFSIZE]; | ||
|
@@ -292,31 +270,26 @@ void handleClientData(int client_sock, std::vector<pollfd>& fds, size_t idx) | |
/// ---------------------------------------- | ||
// Code End | ||
|
||
/** | ||
* Handles the SIGINT signal by printing a message and exiting the program. | ||
* @param sig the signal number | ||
* @return void | ||
* @throws None | ||
*/ | ||
/// @brief Handles the SIGINT signal by printing a message and exiting the program. | ||
/// @param sig the signal number | ||
/// @return void | ||
/// @throws None | ||
static void ft_sigint_handler(int sig) | ||
{ | ||
(void)sig; | ||
std::cout << "\rserver shutting down..." << std::endl; | ||
exit(0); | ||
} | ||
|
||
/** | ||
* The main function of the program. | ||
* It reads the port number from the command line arguments and runs the server. | ||
* | ||
* @param argc The number of command line arguments. | ||
* @param argv An array of character pointers to command line arguments. | ||
* @return The exit status of the program. | ||
* | ||
* The program expects one command line argument: the path to the configuration file. | ||
* If the argument is missing, the program prints the usage message and exits with status 1. | ||
* Otherwise, it runs the server on the specified port. | ||
*/ | ||
/// @brief The main function of the program. | ||
/// It reads the port number from the command line arguments and runs the server. | ||
/// @param argc The number of command line arguments. | ||
/// @param argv An array of character pointers to command line arguments. | ||
/// @return The exit status of the program. | ||
/// | ||
/// The program expects one command line argument: the path to the configuration file. | ||
/// If the argument is missing, the program prints the usage message and exits with status 1. | ||
/// Otherwise, it runs the server on the specified port. | ||
int main(int argc, char *argv[]) | ||
{ | ||
// Check if the correct number of arguments is provided | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
|
||
<head> | ||
<title>Test Page</title> | ||
</head> | ||
|
||
<body> | ||
<h1>Hello, Fruits!</h1> | ||
<ul> | ||
<li>Mango</li> | ||
<li>Banana</li> | ||
<li>Apple</li> | ||
</ul> | ||
</body> | ||
|
||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
|
||
<head> | ||
<title>Test Page</title> | ||
</head> | ||
|
||
<body> | ||
<h1>Hello, Veggies!</h1> | ||
<ul> | ||
<li>Onion</li> | ||
<li>Potato</li> | ||
<li>Cabbage</li> | ||
</ul> | ||
</body> | ||
|
||
</html> |
Oops, something went wrong.