{"id":15047220,"url":"https://github.com/pythongermany/42_webserv","last_synced_at":"2025-05-15T12:31:24.507Z","repository":{"id":201124414,"uuid":"679952697","full_name":"PythonGermany/42_webserv","owner":"PythonGermany","description":"Simple HTTP server written in C++98","archived":false,"fork":false,"pushed_at":"2024-10-29T09:19:14.000Z","size":15388,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-10-29T11:30:07.613Z","etag":null,"topics":["cpp98","http-server"],"latest_commit_sha":null,"homepage":"https://hub.docker.com/r/pythongermany/webserv","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PythonGermany.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-08-18T02:13:29.000Z","updated_at":"2024-10-29T09:15:42.000Z","dependencies_parsed_at":"2024-09-28T23:40:35.155Z","dependency_job_id":"54f0ec16-2f9e-4522-bb9e-6c88805c40c4","html_url":"https://github.com/PythonGermany/42_webserv","commit_stats":{"total_commits":358,"total_committers":11,"mean_commits":32.54545454545455,"dds":0.2821229050279329,"last_synced_commit":"cce15ff87b603c4201c4c7d59975c498daadf81f"},"previous_names":["pythongermany/42_webserv"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PythonGermany%2F42_webserv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PythonGermany%2F42_webserv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PythonGermany%2F42_webserv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PythonGermany%2F42_webserv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PythonGermany","download_url":"https://codeload.github.com/PythonGermany/42_webserv/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254341106,"owners_count":22054982,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp98","http-server"],"created_at":"2024-09-24T20:55:15.350Z","updated_at":"2025-05-15T12:31:24.489Z","avatar_url":"https://github.com/PythonGermany.png","language":"C++","readme":"[![Format check](https://github.com/PythonGermany/42_webserv/actions/workflows/format-check.yml/badge.svg)](https://github.com/PythonGermany/42_webserv/actions/workflows/format-check.yml)\n[![Linux build](https://github.com/PythonGermany/42_webserv/actions/workflows/linux-build.yml/badge.svg)](https://github.com/PythonGermany/42_webserv/actions/workflows/linux-build.yml)\n[![Docker CD](https://github.com/PythonGermany/42_webserv/actions/workflows/docker-cd.yml/badge.svg)](https://github.com/PythonGermany/42_webserv/actions/workflows/docker-cd.yml)\n\n# Introduction\n\nThis project is a basic HTTP server written in C++98. The standards listed below (HTTP/CGI) are not completely implemented and were rather seen as a guideline to implement a usable server than a \"to be followed requirement\".\n\n| Functionality | Description | External info\n| --- | --- | --- | \n| HTTP | HTTP/1.1 | [RFC 2616](https://datatracker.ietf.org/doc/html/rfc2616) / [RFC 9110](https://datatracker.ietf.org/doc/html/rfc9110#section-9.3.7) / [RFC 9112](https://datatracker.ietf.org/doc/html/rfc9112#name-chunked-transfer-coding) |\n| CGI | CGI/1.1 (Tested with php-cgi, using wordpress, and python cgi) | [RFC 3875](https://datatracker.ietf.org/doc/html/rfc3875) |\n| Implemented methods | GET / HEAD / OPTIONS / POST / PUT / DELETE | [RFC 2616 section 5.1.1](https://datatracker.ietf.org/doc/html/rfc2616#section-5.1.1) |\n| Basic cookie support | Tested with wordpress | [RFC 2109](https://datatracker.ietf.org/doc/html/rfc2109) |\n| Argument flags | [To description](#flags) | - |\n| Configuration file | [To description](#configuration) | - |\n\n# Table of Contents\n\n- [Getting started](#getting-started)\n- [Usage](#usage)\n  - [Flags](#flags)\n- [Configuration](#configuration)\n  - [Contexts](#contexts)\n  - [Directives](#directives)\n  - [Example](#example)\n- [Contributors](#contributors)\n\n# Getting started\n\n## Docker\n\n```\ndocker pull pythongermany/webserv\n```\nPull the [docker image](https://hub.docker.com/repository/docker/pythongermany/webserv/general)\n\n```\nmake docker.build\nmake docker.run\n```\nBuild and run the standalone webserver image\n\n```\nmake -C docker up\n```\nCreate a mariadb docker container for the database another container which will setup wordpress, compile webserv execute it. To populate the container env credentials you can make a copy of the [.env-example](docker/.env-example) file and rename it to `.env`, make sure to change the default values according to your needs.\n\n## Compile with make and clang\n\n```\nmake [performance|debug|fsanitize]\n```\n\n# Usage\n```\n./webserv [configuration_file] [ [-i|-h|-v|-c|-t] | [-o|-l|-a|-e ARGUMENT] ...]\n```\nDefault configuration file: `/etc/webserv/webserv.conf`\n\n## Flags\n\nA flag overwrites the default setting as well as the ones that are configured in the config file.\n\n| Flag | Description | Allowed values\n| --- | --- | --- |\n| i | Show info block when starting the server | - |\n| h | Show help message and exit | - |\n| v | Show version of webserv and exit | -\n| c | Show parsed config file structure and exit | - |\n| t | Check if the config file syntax is valid and exit | - |\n| o | Controls [log_to_terminal](#log_to_terminal) | on/off |\n| l | Controls [log_level](#log_level) | 0 / 1 / 2 / 3 / 4 for `error` / `warning` / `info` / `debug` / `verbose`\n| a | Controls [access_log](#access_log) | PATH\n| e | Controls [error_log](#error_log) | PATH\n\n**Flags can be utilized to configure an option directly from the start of the program instead of only after the configuration has been read and parsed.**  \n\n### Example:\n```\n./webserv [configuration_file] -s on -l 2 -a PATH\n```\nYou can look at the parsing debug output by setting the flag `o` to `on` and the flag `l` to `3` or higher, this will override the default setting before the config has been read, parsed and applied. If you also want to write the parsing log messages to a file the flag `a` needs to be set to the `PATH` you want the log file to be. Those steps are necessary because even if you specify all the previous flag settings in the config file they will only be applied after having successfully loaded your config settings, which will, of course, happen after the config file has been parsed.\n\n# Configuration\n\nThe configuration file is used to define the configuration of the webserver. It is composed of directives. A directive is composed of a name arguments and a value. The value can be a string or a block. A block is a list of directives. The file [webserv.conf](conf/webserv.conf) demonstrates the default configuration of the webserv executable.\n\n| Config type | Options |\n| --- | --- |\n| Configuration file context | [http](#http) / [location](#location) / [server](#server) |\n| Configuration file directives | [access_log](#access_log) / [alias](#alias) / [allow](#allow) / [autoindex](#autoindex) / [cgi](#cgi) / [cgi_timeout](#cgi_timeout) / [client_timeout](#client_timout) / [error_log](#error_log) / [error_page](#error_page) / [include](#include) / [index](#index) / [listen](#listen) / [log_level](#log_level) / [log_to_terminal](#log_to_terminal) / [max_client_body_size](#max_client_body_size)  / [redirect](#redirect) / [root](#root) / [server_name](#server_name) / [server_tokens](#server_tokens) / [type](#type) |\n\n## Contexts\n\n### Http\n```nginx\nhttp {\n  include PATH;\n\n  types {\n    [directives]\n  }\n\n  cgi_timeout NUMBER;\n  client_timeout NUMBER;\n\n  access_log PATH;\n  error_log PATH;\n  log_to_terminal [on|off];\n  log_level LEVEL;\n\n  server_tokens [on|off];\n\n  server {\n    [directives]\n  }\n}\n```\nRoot context. It contains the global configuration of the webserver.  \n**Allowed tokens:** [access_log](#access_log) / [cgi_timeout](#cgi_timeout) / [client_timeout](#client_timout)/ [error_log](#error_log) / [include](#include) / [log_level](#log_level) / [log_to_terminal](#log_to_terminal) / [server](#server) / [server_tokens](#server_tokens) / [types](#types)\n\n### Types\n```nginx\ntypes {\n  type MIME_TYPE EXTENSION [EXTENSION ...];\n}\n```\nTypes context. It contains the mime types of the server. The file [mime.types](conf/mime.types) provides an extensive default configuration for this context.  \n**Allowed tokens:** [type](#type)\n\n### Server\n```nginx\nserver {\n  server_tokens [on|off];\n\n  listen HOST:PORT;\n  server_name NAME [NAME ...];\n  root PATH;\n  index FILE [FILE ...];\n\n  autoindex [on|off];\n  max_client_body_size SIZE[k|m];\n  allow METHOD [METHOD ...];\n  error_page CODE PATH;\n  cgi EXTENSION PATH;\n\n  location PATH {\n    [directives]\n  }\n}\n```\nVirtual server context. It contains the configuration of a virtual server.  \n**Allowed tokens:** [allow](#allow) / [autoindex](#autoindex) / [cgi](#cgi) / [error_page](#error_page) / [index](#index) / [listen](#listen) / [location](#location) / [max_client_body_size](#max_client_body_size) / [root](#root) / [server_name](#server_name) / [server_tokens](#server_tokens)\n\n### Location\n```nginx\nlocation PATH {\n  alias PATH;\n  root PATH;\n  index FILE [FILE ...];\n  \n  allow METHOD [METHOD ...];\n  autoindex [on|off];\n  redirect URL;\n  max_client_body_size SIZE;\n  cgi EXTENSTION PATH;\n}\n```\nLocation context for `PATH`. It contains the configuration of a location.  \n**Allowed tokens:** [alias](#alias) / [allow](#allow) / [autoindex](#autoindex) / [cgi](#cgi) / [index](#index) / [max_client_body_size](#max_client_body_size) / [redirect](#redirect) / [root](#root) \n\n## Directives\n\n### access_log\n```nginx\naccess_log PATH;\n```\nSets the path of the access log file.  \nDefault: `/var/log/webserv/access.log`  \n**Allowed in:** [Http](#http)\n\n### alias\n```nginx\nalias PATH;\n```\nSet an alias path. Example request for alias PATH: `GET /LOCATION_CONTEXT_PATH/file` -\u003e `ROOT/PATH/file`  \n**Allowed in:** [Location](#location)\n\n### allow\n```nginx\nallow METHOD [METHOD ...];\n```\nSets the allowed methods for a context.  \nDefault: `GET` / `HEAD` / `OPTIONS`  \n**Allowed in:** [Http](#http) / [Location](#location)\n\n### autoindex\n```nginx\nautoindex [on|off];\n```\nEnables or disables the directory listing for a context  \nDefault: `off`  \n**Allowed in:** [Http](#http) / [Location](#location)\n\n### cgi\n```nginx\ncgi EXTENSTION PATH;\n```\nSets the cgi EXECUTABLE to path for EXTENSION.  \n**Allowed in:** [Location](#location) / [Server](#server)\n\n### cgi_timeout\n```nginx\ncgi_timeout NUMBER;\n```\nSets the cgi timeout in milliseconds.  \nDefault: `30000`  \n**Allowed in:** [Http](#http)\n\n### client_timout\n```nginx\nclient_timout NUMBER;\n```\nSets the client timeout in milliseconds.  \nDefault: `30000`  \n**Allowed in:** [Http](#http)\n\n### error_log\n```nginx\nerror_log PATH;\n```\nSets the path of the error log file.  \nDefault: `/var/log/webserv/error.log`  \n**Allowed in:** [Http](#http)\n\n### error_page\n```nginx\nerror_page CODE PATH;\n```\nSets a custom error page for the given status code.  \n**Allowed in:** [Server](#server)\n\n### include\n```nginx\ninclude PATH;\n```\nInclude other configuration files. Supports `*` wildcard character\n**Allowed in:** [Cgi](#cgi) / [Http](#http) / [Location](#location) / [Server](#server)\n\n### index\n```nginx\nindex FILE [FILE ...];\n```\nSets the index files for a context  \n**Allowed in:** [Location](#location) / [Server](#server)\n\n### listen\n```nginx\nlisten HOST:PORT;\n```\nSets the host and port of the server.  \n**Allowed in:** [Server](#server)\n\n### log_level\n```nginx\nlog_level LEVEL;\n```\nSet the log level. Allowed log levels are `debug`, `info`, `warning`, `error` and `verbose`.  \nDefault: `info`  \n**Allowed in:** [Http](#http)\n\n### log_to_terminal\n```nginx\nlog_to_terminal [on|off];\n```\nSets whether logs should also be displayed on the terminal.  \nDefault: `off`  \n**Allowed in:** [Http](#http)\n\n### max_client_body_size\n```nginx\nmax_client_body_size SIZE[k|m];\n```\nSets the maximum body size for a client request message. 1k is 1024 bytes, 1m is 1024k.  \nDefault: `1m`  \n**Allowed in:** [Location](#location) / [Server](#server)\n\n### redirect\n```nginx\nredirect URL;\n```\nRedirects the request of the context to the given url.   \n**Allowed in:** [Location](#location) / [Server](#server)\n\n### root\n```nginx\nroot PATH;\n```\nSets the root path for a context.  \n**Allowed in:** [Location](#location) / [Server](#server)\n\n### server_name\n```nginx\nserver_name NAME [NAME ...];\n```\nSets the server names.  \n**Allowed in:** [Server](#server)\n\n### server_tokens\n```\nserver_tokens [on|off];\n```\nEnables or disables emitting server version in error messages and in the Server response header field.\n**Allowed in:** [Http](#http) / [Server](#server)\n\n### type\n```nginx\ntype MIME_TYPE EXTENSION [EXTENSION ...];\n```\nSet the mime type for the given extensions.  \n**Allowed in:** [Types](#types)\n\n## Example\n```nginx\n# File -\u003e /etc/webserv/mime.types\ntypes {\n  type text/html html htm;\n  type text/css css;\n  type text/javascript js;\n  type image/jpeg jpeg jpg;\n  type image/png png;\n  type image/svg+xml svg;\n  type image/gif gif;\n}\n```\n```nginx\n# File -\u003e /etc/webserv/webserv.conf\nhttp {\n  include /etc/webserv/mime.types;\n\n  cgi_timeout 30000;\n  client_timeout 30000;\n\n  log_to_terminal off;\n  log_level info;\n  access_log /var/log/webserv/access.log;\n  error_log /var/log/webserv/error.log;\n\n  include /etc/webserv/sites-enabled/*;\n}\n```\n```nginx\n# File -\u003e /etc/webserv/sites-enabled/server.conf\nserver {\n  listen 8080;\n\n  server_tokens on;\n\n  root /var/www/html;\n  index index.html index.htm;\n  autoindex on;\n\n  max_client_body_size 1m;\n  allow GET HEAD OPTIONS;\n  error_page 404 /404.html;\n\n  cgi php /usr/bin/php-cgi;\n\n  location /example {\n    alias /www; # Request: GET /example/file -\u003e ROOT/www/file\n    index example.html;\n\n    allow GET HEAD OPTIONS PUT DELETE;\n    autoindex off;\n  }\n  location /search {\n    redirect https://www.duckduckgo.com;\n  }\n}\n```\n```\n./webserv [-i]\n```\n\n# Contributors\n\n[jharrach](https://github.com/jharrach)\n[PythonGermany](https://github.com/PythonGermany)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpythongermany%2F42_webserv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpythongermany%2F42_webserv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpythongermany%2F42_webserv/lists"}