-
Notifications
You must be signed in to change notification settings - Fork 0
kennyluuluu/Bingit
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
README for cs130 webserver Based on instructions found in https://docs.google.com/document/d/1-BsDsv6BerargpyivX1T6BwPCgQ63pBpczkZajHVOtY/edit#heading=h.b8xr8euy7vvy # How the source code is laid out: The main entry point of our server is found in server_main.cc. From here, it will create a server object, whose details can be found in server.h/.cc. It is capable of creating new sessions (session.h/.cc) when a client connects to our the server. The server object has a member variable called config_params (found in config_params.h/.cc) that parses the config for variables. Here is an example config: ``` port 8080; root /usr/src/projects; handler echo { location /echo; } handler static { location /static; root static; } handler static { location /static2; root /usr/src/projects/public/static; } handler status { location /status; } ``` config_params grabs the port by looking for a statement starting with 'port' with the 2nd token being a number. `root /usr/src/projects` refers to the server root. Meaning all handlers that implement a root variable with a relative path will use the root as the base of the path. As seen in the config, URLs starting with '/static' would serve files out of '/usr/src/projects/static;. It also parses the config looking for something of the format: handler <handler_name> { location <URL path_prefix> <handler specific params> } The handler block must have a non empty name as well as a nonempty token for the location. config_params has a member variable handler_paths that is a map of paths (the location value) to a pair <handler type, NginxConfig>, where the handler type is the string token after 'handler,' and represent what type of handler the config is for (e.g. static or echo). NginxConfig is the child block of the 'handler ######' token and it will be given to each handler's constructor. The server also has a handler_manager (handler_manager.h/.cc) member variable which has a function createByName that, when given a handler name and NginxConfig, creates the corresponding handler. The handler_manager also has member variables that help keep track of certain info that specific handlers may need and passes them to a handler when they are made in createByName if necessary. session (session.h/.cc) will parse the request and use handler_manager to determine which handler is needed and create it. The handlers--such as echo, static, bad_request-- are all from the same interface (handler.h). Handlers will always have a HandleRequest() function that generates a response based on the type of the handler that it is. Sessions are short lived and deleted after writing, making the handlers short lived as well. # How to build, test, and run the code: Assuming you are in the base project directory... Make a "build" directory if one does not already exist `mkdir build` `cd build` We use cmake to help build our project. Modifications can be made in CMakeLists.txt in the base project directory. Our cmake is configured to copy the contents of the static_root dir into the build dir in order to have a more consistent way to access static files. `cmake ..` Now make the binaries using the files generated by cmake `make` Run tests Currently unit tests can be found in the tests directory in the base project directory and integration tests can be found in integration.sh in the base project directory `make test` In order to manually run the server... Assuming you have already run `cmake..` and `make` and are currently in the build directory... `./bin/server ../configs/my_config server is the binary and main entry point for our server and the only parameter is a config file # How to add a request handler and well-documented header files: In order to add a request handler, the new handler must use handler.h as an interface, and implement the following two functions: `static handler* create(const NginxConfig& config, const std::string& root_path)` `virtual std::unique_ptr<reply> HandleRequest(const request& request)` Also, you must add at least one instance of the handler in the config file. Here is the format of a handler config block: `handler <HANDLER NAME> { location <PATH PREFIX IN URL> <HANDLER SPECIFIC PARAMETERS> }` For example, a static handler config block: `handler static { location /static root static }` where location is the prefix in the URL that session will look for. For example `GET /static/index.html` would result in this particular static handler being created and used to parse this request. As seen in the example config, handlers can have variables specific to them. `root` defines what folder this static handler is supposed to look for and serve files out of. The parsing of the NginxConfig block should be done in the constructor of your handler. `create` will be used by `handler_manager:createByName` to create instances of your handler in sessions. Thus, you will need to add the handler and its corresponding name to the if ladder in `createByName` as well. `HandleRequest` will be called by a session after it has parsed the request object. This is the function that determines what your handler does. For example, the static_handler checks if the file path exists, reads the file into a buffer, and appends it as the body of a 200 reply. One last step is to add a new if statement to handler_manager.cc in the function createByName() that, when the name matches your new handler name, will return a unique_ptr to a newly created handler. That statement should also do necessary setup for that specific handler, such as passing specific member variables or info that the handler needs to generate a response correctly.
About
Multipurpose Webserver
Resources
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published