diff --git a/.gitignore b/.gitignore index 0b972a4..7a5f6c1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .DS_Store Thumbs.db *.o +*.d *.swp *.out *.exe @@ -17,3 +18,5 @@ builds ubuntu_tester ubuntu_cgi_tester webserv +!**/webserv/ +*.log diff --git a/Makefile b/Makefile index 03abd77..e454828 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,18 @@ -NAME = webserv -CXX = c++ +NAME = webserv +CXX = c++ -CXXFLAGS = -Wall -Wextra #-Werror -CXXFLAGS += -std=c++98 -CXXFLAGS += -I$(HEADERS_D) -CXXFLAGS += -g -#CXXFLAGS += -O3 +CXXFLAGS = -Wall -Wextra #-Werror +CXXFLAGS += $(HEADERS) +CXXFLAGS += -std=c++98 +CXXFLAGS += -g +CXXFLAGS += -MMD -MP #header dependencie +#CXXFLAGS += -O3 -#SHELL = /bin/zsh -VPATH = $(DIR_SRCS) -DIR_SRCS = srcs +#SHELL = /bin/zsh +VPATH = $(SRCS_D) +HEADERS = $(HEADERS_D:%=-I%) HEADERS_D = ./srcs HEADERS = Webserv.hpp \ ConfigParser.hpp \ @@ -22,15 +23,18 @@ HEADERS = Webserv.hpp \ MethodType.hpp \ utils.hpp \ -DEPENDENCIES = $(HEADERS:%=$(HEADERS_D)/%) +SRCS_D = srcs srcs/webserv +SRCS = main.cpp \ + ft_itoa.cpp \ + base.cpp init.cpp close.cpp epoll_update.cpp signal.cpp \ + accept.cpp request.cpp response.cpp \ + run_loop.cpp \ + ConfigParser.cpp \ + utils.cpp \ -SRCS = main.cpp \ - Webserv.cpp \ - ConfigParser.cpp \ - utils.cpp \ - -DIR_OBJS = builds -OBJS = $(SRCS:%.cpp=$(DIR_OBJS)/%.o) +OBJS_D = builds +OBJS = $(SRCS:%.cpp=$(OBJS_D)/%.o) +DEPS = $(OBJS:.o=.d) #header dependencie # -------------------- # ------ RULES ------- @@ -38,26 +42,24 @@ OBJS = $(SRCS:%.cpp=$(DIR_OBJS)/%.o) all: $(NAME) -$(DIR_OBJS)/%.o: %.cpp | $(DIR_OBJS) +$(OBJS_D)/%.o: %.cpp | $(OBJS_D) $(CXX) $(CXXFLAGS) -c $< -o $@ -$(DIR_OBJS): +$(OBJS_D): mkdir $@ -$(OBJS): $(DEPENDENCIES) -#$(OBJS): $(DEPENDENCIES) Makefile - -$(NAME) : $(OBJS) - $(CXX) $(OBJS) -o $(NAME) +$(NAME): $(OBJS) + $(CXX) $^ -o $(NAME) clean: - rm -f $(OBJS) + rm -rf $(OBJS_D) fclean: clean rm -f $(NAME) re: fclean all -#run: all +.PHONY : all clean fclean re + +-include $(DEPS) # header dependencie -.PHONY : all clean fclean re run diff --git a/default_error_pages/404.html b/default_error_pages/404.html new file mode 100644 index 0000000..df4d27c --- /dev/null +++ b/default_error_pages/404.html @@ -0,0 +1,11 @@ + + + + 404 Not Found + + +

404 Not Found

+
+

Le Webserv/0.1

+ + \ No newline at end of file diff --git a/srcs/Client.hpp b/srcs/Client.hpp index 9092f31..2536012 100644 --- a/srcs/Client.hpp +++ b/srcs/Client.hpp @@ -6,9 +6,9 @@ # include # include -class Client +struct Client { - public: + // public: // Client(Placeholder); // Client(); // Client(Client const &src); @@ -18,9 +18,11 @@ class Client int fd; std::string raw_request; std::map request; - std::map response; + // std::map response; + std::string response; + unsigned int status; - private: + // private: }; diff --git a/srcs/Webserv.hpp b/srcs/Webserv.hpp index 4d5b039..015669b 100644 --- a/srcs/Webserv.hpp +++ b/srcs/Webserv.hpp @@ -35,17 +35,14 @@ # include # include # include +# include // itoa +# include // ifstream +char *ft_itoa(int n); +# include // access -# define BUFSIZE 8192 -# define TIMEOUT 3000 -# define MAX_EVENTS 42 // arbitrary -# define MSG_TEST "Le Webserv / 20 =D\n" - - -// ev.data.u32 filled with tag constant "SERVER_FD/CLIENT_FD" -// dont work because ev.data is an "union", -// so we can only use one variable (fd, ptr, u32 or u64) - // ev.data.u32 = SERVER_FD; +extern bool g_run; +extern int g_last_signal; +void signal_handler(int signum); /* enum // WIP test { @@ -67,7 +64,7 @@ struct s // WIP test class Webserv { public: - + // base.cpp Webserv(); // Webserv(Webserv const &src); @@ -77,8 +74,10 @@ class Webserv ~Webserv(); // Webserv &operator=(Webserv const &rhs); + // init.cpp void init_virtual_servers(); // ADD config param - void start(); + // run_loop.cpp + void run(); private: int _epfd; @@ -86,19 +85,26 @@ class Webserv // std::vector _servers; std::vector _clients; + // accept.cpp void _accept_connection(int fd); + // request.cpp + void _request(Client *client); void _read_request(Client *client); + // response.cpp + void _response(Client *client); void _send_response(Client *client); - + void _construct_response(Client *client); + void _insert_status_line(Client *client); + void _get_ressource(Client *client); + // epoll_update.cpp int _epoll_update(int fd, uint32_t events, int op); int _epoll_update(int fd, uint32_t events, int op, void *ptr); - + // signal.cpp void _handle_last_signal(); - // void _signal_handler(int signum); // invalide dans une class - Client* _actual_client; + // close.cpp void _close_client(int fd); void _close_all_clients(); - + // init.cpp void _bind(int socket_fd, in_port_t port); void _listen(int socket_fd, unsigned int max_connections); }; diff --git a/srcs/ft_itoa.cpp b/srcs/ft_itoa.cpp new file mode 100644 index 0000000..1e996a9 --- /dev/null +++ b/srcs/ft_itoa.cpp @@ -0,0 +1,50 @@ + +#include + +static int eval_is_negative(int *n) +{ + if (*n < 0) + { + *n = *n * -1; + return (1); + } + return (0); +} + +static int eval_digit_nbr(int n) +{ + int digit_nbr; + + if (n == 0) + return (1); + digit_nbr = 0; + while (n != 0) + { + digit_nbr++; + n = n / 10; + } + return (digit_nbr); +} + +char *ft_itoa(int n) +{ + int i; + char *str; + int is_negative; + + if (n == -2147483648) + return (strdup("-2147483648")); + is_negative = eval_is_negative(&n); + i = eval_digit_nbr(n) + is_negative; + str = new char[i+1]; + if (is_negative) + str[0] = '-'; + str[i] = '\0'; + while (i > 0 + is_negative) + { + i--; + str[i] = (n % 10) + '0'; + n = n / 10; + } + return (str); +} diff --git a/srcs/webserv/accept.cpp b/srcs/webserv/accept.cpp new file mode 100644 index 0000000..cd67904 --- /dev/null +++ b/srcs/webserv/accept.cpp @@ -0,0 +1,26 @@ + +#include "Webserv.hpp" + +void Webserv::_accept_connection(int fd) +{ + struct sockaddr_in addr; + socklen_t addr_len; + int accepted_fd; + + std::cerr << "accept()\n"; + addr_len = sizeof addr; + accepted_fd = ::accept(fd, (sockaddr*)&addr, &addr_len); + if (accepted_fd == -1) + { + std::perror("err accept()"); + if (g_last_signal) + _handle_last_signal(); + return ; + } + ::fcntl(accepted_fd, F_SETFL, O_NONBLOCK); + + _clients.push_back(Client()); + _clients.back().fd = accepted_fd; + + _epoll_update(accepted_fd, EPOLLIN, EPOLL_CTL_ADD, &_clients.back()); +} diff --git a/srcs/webserv/base.cpp b/srcs/webserv/base.cpp new file mode 100644 index 0000000..f4d4e0d --- /dev/null +++ b/srcs/webserv/base.cpp @@ -0,0 +1,54 @@ + +#include "Webserv.hpp" + +Webserv::Webserv() +{ + std::cerr << "Server init\n"; + + _epfd = ::epoll_create1(0); // (EPOLL_CLOEXEC) for CGI fork ? + if (_epfd == -1) + { + std::perror("err epoll_create1()"); + throw std::runtime_error("Epoll init"); + } + + std::signal(SIGPIPE, signal_handler); + std::signal(SIGINT, signal_handler); +} + +/* Webserv::Webserv(Webserv const &src) +{ + +} */ + +// we'll come back to this +/* +Webserv::Webserv(std::vector* servers) +: _servers(servers) +{ + // talk to luke about what all this does + // the Param Constructor might need to do dif stuff + std::cout << "Server init\n"; + + _epfd = ::epoll_create1(0); // (EPOLL_CLOEXEC) for CGI fork ? + if (_epfd == -1) + { + std::perror("err epoll_create1(): "); + throw std::runtime_error("Epoll init"); + } +} +*/ + + +Webserv::~Webserv() +{ + close(_socket_fd); + close(_epfd); + _close_all_clients(); + std::cerr << "Server destroyed\n"; +} + +/* Webserv & Webserv::operator=(Webserv const &rhs) +{ + +} */ diff --git a/srcs/webserv/close.cpp b/srcs/webserv/close.cpp new file mode 100644 index 0000000..f4bc0b9 --- /dev/null +++ b/srcs/webserv/close.cpp @@ -0,0 +1,34 @@ + +#include "Webserv.hpp" + +void Webserv::_close_client(int fd) +{ + std::vector::iterator it = _clients.begin(); + while (it != _clients.end()) + { + if (it->fd == fd) + { + // _epoll_update(fd, 0, EPOLL_CTL_DEL); // normalement superflu, DEBUG + if (::close(fd) == -1) + std::perror("err close()"); + else + std::cerr << "close fd " << fd << "\n"; + _clients.erase(it); + break; + } + ++it; + } +} + +void Webserv::_close_all_clients() +{ + while (!_clients.empty()) + { + // _epoll_update(_clients.back().fd, 0, EPOLL_CTL_DEL); // normalement superflu, DEBUG + if (::close(_clients.back().fd) == -1) + std::perror("err close()"); + else + std::cerr << "close fd " << _clients.back().fd << "\n"; + _clients.pop_back(); + } +} diff --git a/srcs/webserv/epoll_update.cpp b/srcs/webserv/epoll_update.cpp new file mode 100644 index 0000000..bfe0770 --- /dev/null +++ b/srcs/webserv/epoll_update.cpp @@ -0,0 +1,30 @@ + +#include "Webserv.hpp" + +int Webserv::_epoll_update(int fd, uint32_t events, int op) +{ + struct epoll_event ev; + std::memset(&ev, 0, sizeof ev); + ev.events = events; + ev.data.fd = fd; + if (::epoll_ctl(_epfd, op, fd, &ev) == -1) + { + std::perror("err _epoll_update()"); + return (-1); + } + return (0); +} + +int Webserv::_epoll_update(int fd, uint32_t events, int op, void *ptr) +{ + struct epoll_event ev; + std::memset(&ev, 0, sizeof ev); + ev.events = events; + ev.data.ptr = ptr; + if (::epoll_ctl(_epfd, op, fd, &ev) == -1) + { + std::perror("err _epoll_update()"); + return (-1); + } + return (0); +} diff --git a/srcs/webserv/init.cpp b/srcs/webserv/init.cpp new file mode 100644 index 0000000..97a3b90 --- /dev/null +++ b/srcs/webserv/init.cpp @@ -0,0 +1,45 @@ + +#include "Webserv.hpp" + +void Webserv::init_virtual_servers() // ADD config param +{ + _socket_fd = ::socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); // (SOCK_CLOEXEC) for CGI fork ? + if (_socket_fd == -1) + { + std::perror("err socket()"); + throw std::runtime_error("Socket init"); + } + + _bind(_socket_fd, 4040); + _listen(_socket_fd, 512); // 512 arbitrary + + if (_epoll_update(_socket_fd, EPOLLIN, EPOLL_CTL_ADD) == -1) + throw std::runtime_error("Socket init"); +} + +void Webserv::_bind(int socket_fd, in_port_t port) +{ + // cast invalid ? how to ? + // const struct sockaddr* cast_test = static_cast(addr); + + struct sockaddr_in addr; + std::memset(&addr, 0, sizeof addr); + addr.sin_family = AF_INET; + addr.sin_port = ::htons(port); + addr.sin_addr.s_addr = ::htonl(INADDR_ANY); // htonl useless with 0 value (INADDR_ANY) ? + + if (::bind(socket_fd, (const sockaddr*)&addr, sizeof addr) == -1) + { + std::perror("err bind()"); + throw std::runtime_error("Socket bind"); + } +} + +void Webserv::_listen(int socket_fd, unsigned int max_connections) +{ + if (::listen(socket_fd, max_connections) == -1) + { + std::perror("err listen()"); + throw std::runtime_error("Socket listen"); + } +} diff --git a/srcs/webserv/request.cpp b/srcs/webserv/request.cpp new file mode 100644 index 0000000..17c372b --- /dev/null +++ b/srcs/webserv/request.cpp @@ -0,0 +1,37 @@ + +#include "Webserv.hpp" + +#define BUFSIZE 8192 + +void Webserv::_request(Client *client) +{ + _read_request(client); + if (g_last_signal) + _handle_last_signal(); +} + +void Webserv::_read_request(Client *client) +{ + char buf[BUFSIZE+1]; + ssize_t ret; + + std::cerr << "recv()\n"; + ret = ::recv(client->fd, buf, BUFSIZE, 0); + if (ret == -1) + { + std::perror("err recv()"); + std::cerr << "client ptr =" << client << "\n"; // DEBUG + std::cerr << "client.fd =" << client->fd << "\n"; // DEBUG + _close_client(client->fd); + return ; + } + /* + if (ret == BUFSIZE) + // send error like "request too long" to client + */ + + buf[ret] = '\0'; + client->raw_request.append(buf); + + _epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD, client); +} diff --git a/srcs/webserv/response.cpp b/srcs/webserv/response.cpp new file mode 100644 index 0000000..ce785ed --- /dev/null +++ b/srcs/webserv/response.cpp @@ -0,0 +1,143 @@ + +#include "Webserv.hpp" + +void Webserv::_response(Client *client) +{ + _send_response(client); + if (g_last_signal) + _handle_last_signal(); +} + +void Webserv::_send_response(Client *client) +{ + ssize_t ret; + + std::cerr << "send()\n"; + std::cerr << "RAW_REQUEST\n|\n" << client->raw_request << "|\n"; // DEBUG + + _construct_response(client); + + ret = ::send(client->fd, client->response.data(), client->response.size(), 0); + if (ret == -1) + { + std::perror("err send()"); + std::cerr << "client ptr =" << client << "\n"; // DEBUG + std::cerr << "client.fd =" << client->fd << "\n"; // DEBUG + _close_client(client->fd); + return ; + } + + _close_client(client->fd); + /* if (client->raw_request.find("Connection: keep-alive") == std::string::npos) + _close_client(client->fd); + else + { + _epoll_update(client->fd, EPOLLIN, EPOLL_CTL_MOD, client); + client->raw_request.clear(); + client->response.clear(); + } */ +} + +void Webserv::_construct_response(Client *client) +{ + client->status = 200; + client->response.append("Server: Webserv/0.1\r\n"); + + client->response.append("Connection: close\r\n"); + + _get_ressource(client); + + _insert_status_line(client); +} + +#define E404 "\r\n404 Not Found

404 Not Found


Le Webserv/0.1

" +#define E500 "\r\n500 Internal Server Error

500 Internal Server Error


Le Webserv/0.1

" +void Webserv::_insert_status_line(Client *client) +{ + std::string status_line; + + status_line.append("HTTP/1.1 "); + // WIP, maybe make a map for status response + switch (client->status) + { + case (200): + status_line.append("200 OK"); + break; + case (404): + status_line.append("404 Not Found"); + client->response.append(E404); + break; + case (500): + status_line.append("500 Internal Server Error"); + client->response.append(E500); + break; + } + status_line.append("\r\n"); + + client->response.insert(0, status_line); +} + +#define ROOT "website" +#define INDEX "index.html" +#define MAX_FILESIZE 1000000 // (1Mo) +void Webserv::_get_ressource(Client *client) +{ + std::ifstream ifd; // For chunk, ifstream directly in struct CLient for multiples read without close() ? + char buf[MAX_FILESIZE+1]; + char *tmp; + + // Mini parsing à l'arrache du PATH + std::string path; + path = client->raw_request.substr(0, client->raw_request.find("\r\n")); + path = path.substr(0, path.rfind(" ")); + path = path.substr(path.find("/")); + if (path == "/") + path.append(INDEX); + path.insert(0, ROOT); + + if (access(path.data(), R_OK) == -1) + { + std::perror("err access()"); + client->status = 404; + return ; + } + + ifd.open(path.data(), std::ios::binary | std::ios::ate); // std::ios::binary (binary for files like images ?) + if (!ifd) + { + std::cerr << path << ": open fail" << '\n'; + client->status = 500; + } + else + { + // WIP : Chunk or not chunk (if filesize too big) + std::streampos size = ifd.tellg(); + if (size > MAX_FILESIZE) + { + // Then chunk + client->status = 500; // WIP temp + std::cerr << "File too large for non chunk body\n"; + ifd.close(); + return ; + } + + ifd.seekg(0, std::ios::beg); + ifd.read(buf, size); + buf[ifd.gcount()] = '\0'; + + client->response.append("Content-Type: text/html; charset=UTF-8\r\n"); + + client->response.append("Content-Length: "); + tmp = ::ft_itoa(ifd.gcount()); + client->response.append(tmp); + delete tmp; + client->response.append("\r\n"); + + // Body + client->response.append("\r\n"); + client->response.append(buf); + + + ifd.close(); + } +} diff --git a/srcs/webserv/run_loop.cpp b/srcs/webserv/run_loop.cpp new file mode 100644 index 0000000..9b466b5 --- /dev/null +++ b/srcs/webserv/run_loop.cpp @@ -0,0 +1,48 @@ + +#include "Webserv.hpp" + +#define MAX_EVENTS 42 // arbitrary +#define TIMEOUT 3000 + +void Webserv::run() +{ + std::cerr << "Server started\n"; + struct epoll_event events[MAX_EVENTS]; + int nfds; + int i; + int count_loop = 0; + + g_run = true; + while (g_run) + { + std::cerr << ++count_loop << "----loop epoll()\n"; + nfds = ::epoll_wait(_epfd, events, MAX_EVENTS, TIMEOUT); + if (nfds == -1) + { + std::perror("err epoll_wait()"); + throw std::runtime_error("Epoll wait"); + } + else if (nfds == 0) + { + if (!_clients.empty()) + { + std::cerr << "Timeout " << TIMEOUT << "ms\n"; + _close_all_clients(); + } + } + i = 0; + while (i < nfds) + { + // if ((events[i].data.u32 == SERVER_FD) && (events[i].events & EPOLLIN)) // Dont work, see "SERVER_FD" define + if ((events[i].data.fd == _socket_fd) && (events[i].events & EPOLLIN)) + _accept_connection(events[i].data.fd); + else if (events[i].events & EPOLLIN) + _request(static_cast(events[i].data.ptr)); + else if (events[i].events & EPOLLOUT) + _response(static_cast(events[i].data.ptr)); + ++i; + if (!g_run) + break; + } + } +} diff --git a/srcs/webserv/signal.cpp b/srcs/webserv/signal.cpp new file mode 100644 index 0000000..1074f26 --- /dev/null +++ b/srcs/webserv/signal.cpp @@ -0,0 +1,29 @@ + +#include "Webserv.hpp" + +bool g_run; +int g_last_signal; + +void signal_handler(int signum) +{ + g_last_signal = signum; +} + +void Webserv::_handle_last_signal() +{ + if (g_last_signal == SIGPIPE) + { + std::cerr << "SIGPIPE\n"; + // if (_actual_client) + // { + // _close_client(_actual_client->fd); + // _actual_client = NULL; + // } + } + else if (g_last_signal == SIGINT) + { + g_run = false; + // maybe a throw here instead of "g_run" ? + } + g_last_signal = 0; +} diff --git a/website/index.html b/website/index.html new file mode 100644 index 0000000..bc65643 --- /dev/null +++ b/website/index.html @@ -0,0 +1,11 @@ + + + + Le Webserv + + +

Le index (˘ ͜ʖ˘)

+
+

(˚3˚)

+ + \ No newline at end of file diff --git a/website/rfc2119_no_link.html b/website/rfc2119_no_link.html new file mode 100644 index 0000000..eec8fe5 --- /dev/null +++ b/website/rfc2119_no_link.html @@ -0,0 +1,300 @@ + + + + rfc2119 + + +
+This is a purely informative rendering of an RFC that includes verified errata. This rendering may not be used as a reference. +
+
+The following 'Verified' errata have been incorporated in this document: + EID 493, EID 494, EID 495, EID 496, EID 498, EID 499, EID 500, EID 5101 +
+ +
Network Working Group                                         S. Bradner
+Request for Comments: 2119                            Harvard University
+BCP: 14                                                       March 1997
+Category: Best Current Practice
+
+
+        Key words for use in RFCs to Indicate Requirement Levels
+
+Status of this Memo
+
+   This document specifies an Internet Best Current Practices for the
+   Internet Community, and requests discussion and suggestions for
+   improvements.  Distribution of this memo is unlimited.
+
+Abstract
+
+   In many standards track documents several words are used to signify
+   the requirements in the specification.  These words are often
+   capitalized.  This document defines these words as they should be
+   interpreted in IETF documents.  Authors who follow these guidelines
+   should incorporate this phrase near the beginning of their document:
+
+             The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL 
+       NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT 
+       RECOMMENDED",  "MAY", and "OPTIONAL" in this document are to 
+       be interpreted as described in RFC 2119.
+
+
EID 499 (Verified) is as follows:
+
+Section: Abstract
+
+Original Text:
+
+       The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
+       NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", and
+       "OPTIONAL" in this document are to be interpreted as described in
+       RFC 2119.
+
+Corrected Text:
+
+       The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
+       NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT 
+       RECOMMENDED",  "MAY", and "OPTIONAL" in this document are to 
+       be interpreted as described in RFC 2119.
+
+Notes:
+The phrase "NOT RECOMMENDED" is missing from this sentence. +
+
+ Note that the force of these words is modified by the requirement + level of the document in which they are used. + +1. MUST This word, or the terms "REQUIRED" or "SHALL", means that the + definition is an absolute requirement of the specification. +
+
EID 493 (Verified) is as follows:
+
+Section: 1
+
+Original Text:
+
+2. MUST NOT   This phrase, or the phrase "SHALL NOT", mean that the
+   definition is an absolute prohibition of the specification.
+
+Corrected Text:
+
+2. MUST NOT   This phrase, or the phrase "SHALL NOT", means that the
+   definition is an absolute prohibition of the specification.
+
+Notes:
+ +
+
+
EID 498 (Verified) is as follows:
+
+Section: 1
+
+Original Text:
+
+4. SHOULD NOT   This phrase, or the phrase "NOT RECOMMENDED" mean that
+   there may exist valid reasons in particular circumstances when the
+   particular behavior is acceptable or even useful, but the full
+   implications should be understood and the case carefully weighed
+   before implementing any behavior described with this label.
+
+Corrected Text:
+
+4. SHOULD NOT   This phrase, or the phrase "NOT RECOMMENDED", means that
+   there may exist valid reasons in particular circumstances when the
+   particular behavior is acceptable or even useful, but the full
+   implications should be understood and the case carefully weighed
+   before implementing any behavior described with this label.
+
+Notes:
+ +
+
+
EID 500 (Verified) is as follows:
+
+Section: 1
+
+Original Text:
+
+3. SHOULD   This word, or the adjective "RECOMMENDED", mean that there
+   may exist valid reasons in particular circumstances to ignore a
+   particular item, but the full implications must be understood and
+   carefully weighed before choosing a different course.
+
+Corrected Text:
+
+3. SHOULD   This word, or the adjective "RECOMMENDED", means that there
+   may exist valid reasons in particular circumstances to ignore a
+   particular item, but the full implications must be understood and
+   carefully weighed before choosing a different course.
+
+Notes:
+ +
+
+
+
EID 495 (Verified) is as follows:
+
+Section: 1
+
+Original Text:
+
+1. MUST   This word, or the terms "REQUIRED" or "SHALL", mean that the
+   definition is an absolute requirement of the specification.
+
+
+Corrected Text:
+
+1. MUST   This word, or the terms "REQUIRED" or "SHALL", means that the
+   definition is an absolute requirement of the specification.
+
+Notes:
+ +
+
+2. MUST NOT This phrase, or the phrase "SHALL NOT", mean that the + definition is an absolute prohibition of the specification. + +3. SHOULD This word, or the adjective "RECOMMENDED", mean that there + may exist valid reasons in particular circumstances to ignore a + particular item, but the full implications must be understood and + carefully weighed before choosing a different course. + +4. SHOULD NOT This phrase, or the phrase "NOT RECOMMENDED" mean that + there may exist valid reasons in particular circumstances when the + particular behavior is acceptable or even useful, but the full + implications should be understood and the case carefully weighed + before implementing any behavior described with this label. + +5. MAY This word, or the adjective "OPTIONAL", mean that an item is + truly optional. One vendor may choose to include the item because a + particular marketplace requires it or because the vendor feels that + it enhances the product while another vendor may omit the same item. + An implementation which does not include a particular option MUST be + prepared to interoperate with another implementation which does + include the option, though perhaps with reduced functionality. In the + same vein an implementation which does include a particular option + MUST be prepared to interoperate with another implementation which + does not include the option (except, of course, for the feature the + option provides). +
+
EID 5101 (Verified) is as follows:
+
+Section: 5
+
+Original Text:
+
+5. MAY   This word, or the adjective "OPTIONAL", mean that an item is
+   truly optional.  One vendor may choose to include the item because a
+   particular marketplace requires it or because the vendor feels that
+   it enhances the product while another vendor may omit the same item.
+   An implementation which does not include a particular option MUST be
+   prepared to interoperate with another implementation which does
+   include the option, though perhaps with reduced functionality. In the
+   same vein an implementation which does include a particular option
+   MUST be prepared to interoperate with another implementation which
+   does not include the option (except, of course, for the feature the
+   option provides.)
+
+Corrected Text:
+
+5. MAY   This word, or the adjective "OPTIONAL", mean that an item is
+   truly optional.  One vendor may choose to include the item because a
+   particular marketplace requires it or because the vendor feels that
+   it enhances the product while another vendor may omit the same item.
+   An implementation which does not include a particular option MUST be
+   prepared to interoperate with another implementation which does
+   include the option, though perhaps with reduced functionality. In the
+   same vein an implementation which does include a particular option
+   MUST be prepared to interoperate with another implementation which
+   does not include the option (except, of course, for the feature the
+   option provides).
+
+Notes:
+Full stop should appear outside the parentheses in the last sentence. +
+
+6. Guidance in the use of these Imperatives + + Imperatives of the type defined in this memo must be used with care + and sparingly. In particular, they MUST only be used where it is + actually required for interoperation or to limit behavior which has + potential for causing harm (e.g., limiting retransmissions) For +
+
EID 494 (Verified) is as follows:
+
+Section: 6
+
+Original Text:
+
+(e.g., limiting retransmisssions)
+
+Corrected Text:
+
+(e.g., limiting retransmissions)
+
+Notes:
+ +
+
+
EID 496 (Verified) is as follows:
+
+Section: 6
+
+Original Text:
+
+   In particular, they MUST only be used where it is actually required
+   for interoperation or to limit behavior which has potential for
+   causing harm (e.g., limiting retransmisssions)  For example, they
+   must not be used to try to impose a particular method on
+   implementors where the method is not required for interoperability.   
+
+Corrected Text:
+
+   In particular, they MUST only be used where it is actually required
+   for interoperation or to limit behavior which has potential for
+   causing harm (e.g., limiting retransmissions).  For example, they
+   must not be used to try to impose a particular method on
+   implementors where the method is not required for interoperability.
+
+Notes:
+ +
+
example, they must not be used to try to impose a particular method + on implementors where the method is not required for + interoperability. + +7. Security Considerations + + These terms are frequently used to specify behavior with security + implications. The effects on security of not implementing a MUST or + SHOULD, or doing something the specification says MUST NOT or SHOULD + NOT be done may be very subtle. Document authors should take the time + to elaborate the security implications of not following + recommendations or requirements as most implementors will not have + had the benefit of the experience and discussion that produced the + specification. + +8. Acknowledgments + + The definitions of these terms are an amalgam of definitions taken + from a number of RFCs. In addition, suggestions have been + incorporated from a number of people including Robert Ullmann, Thomas + Narten, Neal McBurnett, and Robert Elz. + +9. Author's Address + + Scott Bradner + Harvard University + 1350 Mass. Ave. + Cambridge, MA 02138 + + phone - +1 617 495 3864 + + email - sob@harvard.edu + + + + + + +
\ No newline at end of file diff --git a/website/rfc2119_sigabrt.html b/website/rfc2119_sigabrt.html new file mode 100644 index 0000000..18be9ac --- /dev/null +++ b/website/rfc2119_sigabrt.html @@ -0,0 +1,312 @@ + + + + + + + + + rfc2119 + + + + + + + + + +
+This is a purely informative rendering of an RFC that includes verified errata. This rendering may not be used as a reference. +
+
+The following 'Verified' errata have been incorporated in this document: + EID 493, EID 494, EID 495, EID 496, EID 498, EID 499, EID 500, EID 5101 +
+ +
Network Working Group                                         S. Bradner
+Request for Comments: 2119                            Harvard University
+BCP: 14                                                       March 1997
+Category: Best Current Practice
+
+
+        Key words for use in RFCs to Indicate Requirement Levels
+
+Status of this Memo
+
+   This document specifies an Internet Best Current Practices for the
+   Internet Community, and requests discussion and suggestions for
+   improvements.  Distribution of this memo is unlimited.
+
+Abstract
+
+   In many standards track documents several words are used to signify
+   the requirements in the specification.  These words are often
+   capitalized.  This document defines these words as they should be
+   interpreted in IETF documents.  Authors who follow these guidelines
+   should incorporate this phrase near the beginning of their document:
+
+             The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL 
+       NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT 
+       RECOMMENDED",  "MAY", and "OPTIONAL" in this document are to 
+       be interpreted as described in RFC 2119.
+
+
EID 499 (Verified) is as follows:
+
+Section: Abstract
+
+Original Text:
+
+       The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
+       NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", and
+       "OPTIONAL" in this document are to be interpreted as described in
+       RFC 2119.
+
+Corrected Text:
+
+       The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
+       NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT 
+       RECOMMENDED",  "MAY", and "OPTIONAL" in this document are to 
+       be interpreted as described in RFC 2119.
+
+Notes:
+The phrase "NOT RECOMMENDED" is missing from this sentence. +
+
+ Note that the force of these words is modified by the requirement + level of the document in which they are used. + +1. MUST This word, or the terms "REQUIRED" or "SHALL", means that the + definition is an absolute requirement of the specification. +
+
EID 493 (Verified) is as follows:
+
+Section: 1
+
+Original Text:
+
+2. MUST NOT   This phrase, or the phrase "SHALL NOT", mean that the
+   definition is an absolute prohibition of the specification.
+
+Corrected Text:
+
+2. MUST NOT   This phrase, or the phrase "SHALL NOT", means that the
+   definition is an absolute prohibition of the specification.
+
+Notes:
+ +
+
+
EID 498 (Verified) is as follows:
+
+Section: 1
+
+Original Text:
+
+4. SHOULD NOT   This phrase, or the phrase "NOT RECOMMENDED" mean that
+   there may exist valid reasons in particular circumstances when the
+   particular behavior is acceptable or even useful, but the full
+   implications should be understood and the case carefully weighed
+   before implementing any behavior described with this label.
+
+Corrected Text:
+
+4. SHOULD NOT   This phrase, or the phrase "NOT RECOMMENDED", means that
+   there may exist valid reasons in particular circumstances when the
+   particular behavior is acceptable or even useful, but the full
+   implications should be understood and the case carefully weighed
+   before implementing any behavior described with this label.
+
+Notes:
+ +
+
+
EID 500 (Verified) is as follows:
+
+Section: 1
+
+Original Text:
+
+3. SHOULD   This word, or the adjective "RECOMMENDED", mean that there
+   may exist valid reasons in particular circumstances to ignore a
+   particular item, but the full implications must be understood and
+   carefully weighed before choosing a different course.
+
+Corrected Text:
+
+3. SHOULD   This word, or the adjective "RECOMMENDED", means that there
+   may exist valid reasons in particular circumstances to ignore a
+   particular item, but the full implications must be understood and
+   carefully weighed before choosing a different course.
+
+Notes:
+ +
+
+
+
EID 495 (Verified) is as follows:
+
+Section: 1
+
+Original Text:
+
+1. MUST   This word, or the terms "REQUIRED" or "SHALL", mean that the
+   definition is an absolute requirement of the specification.
+
+
+Corrected Text:
+
+1. MUST   This word, or the terms "REQUIRED" or "SHALL", means that the
+   definition is an absolute requirement of the specification.
+
+Notes:
+ +
+
+2. MUST NOT This phrase, or the phrase "SHALL NOT", mean that the + definition is an absolute prohibition of the specification. + +3. SHOULD This word, or the adjective "RECOMMENDED", mean that there + may exist valid reasons in particular circumstances to ignore a + particular item, but the full implications must be understood and + carefully weighed before choosing a different course. + +4. SHOULD NOT This phrase, or the phrase "NOT RECOMMENDED" mean that + there may exist valid reasons in particular circumstances when the + particular behavior is acceptable or even useful, but the full + implications should be understood and the case carefully weighed + before implementing any behavior described with this label. + +5. MAY This word, or the adjective "OPTIONAL", mean that an item is + truly optional. One vendor may choose to include the item because a + particular marketplace requires it or because the vendor feels that + it enhances the product while another vendor may omit the same item. + An implementation which does not include a particular option MUST be + prepared to interoperate with another implementation which does + include the option, though perhaps with reduced functionality. In the + same vein an implementation which does include a particular option + MUST be prepared to interoperate with another implementation which + does not include the option (except, of course, for the feature the + option provides). +
+
EID 5101 (Verified) is as follows:
+
+Section: 5
+
+Original Text:
+
+5. MAY   This word, or the adjective "OPTIONAL", mean that an item is
+   truly optional.  One vendor may choose to include the item because a
+   particular marketplace requires it or because the vendor feels that
+   it enhances the product while another vendor may omit the same item.
+   An implementation which does not include a particular option MUST be
+   prepared to interoperate with another implementation which does
+   include the option, though perhaps with reduced functionality. In the
+   same vein an implementation which does include a particular option
+   MUST be prepared to interoperate with another implementation which
+   does not include the option (except, of course, for the feature the
+   option provides.)
+
+Corrected Text:
+
+5. MAY   This word, or the adjective "OPTIONAL", mean that an item is
+   truly optional.  One vendor may choose to include the item because a
+   particular marketplace requires it or because the vendor feels that
+   it enhances the product while another vendor may omit the same item.
+   An implementation which does not include a particular option MUST be
+   prepared to interoperate with another implementation which does
+   include the option, though perhaps with reduced functionality. In the
+   same vein an implementation which does include a particular option
+   MUST be prepared to interoperate with another implementation which
+   does not include the option (except, of course, for the feature the
+   option provides).
+
+Notes:
+Full stop should appear outside the parentheses in the last sentence. +
+
+6. Guidance in the use of these Imperatives + + Imperatives of the type defined in this memo must be used with care + and sparingly. In particular, they MUST only be used where it is + actually required for interoperation or to limit behavior which has + potential for causing harm (e.g., limiting retransmissions) For +
+
EID 494 (Verified) is as follows:
+
+Section: 6
+
+Original Text:
+
+(e.g., limiting retransmisssions)
+
+Corrected Text:
+
+(e.g., limiting retransmissions)
+
+Notes:
+ +
+
+
EID 496 (Verified) is as follows:
+
+Section: 6
+
+Original Text:
+
+   In particular, they MUST only be used where it is actually required
+   for interoperation or to limit behavior which has potential for
+   causing harm (e.g., limiting retransmisssions)  For example, they
+   must not be used to try to impose a particular method on
+   implementors where the method is not required for interoperability.   
+
+Corrected Text:
+
+   In particular, they MUST only be used where it is actually required
+   for interoperation or to limit behavior which has potential for
+   causing harm (e.g., limiting retransmissions).  For example, they
+   must not be used to try to impose a particular method on
+   implementors where the method is not required for interoperability.
+
+Notes:
+ +
+
example, they must not be used to try to impose a particular method + on implementors where the method is not required for + interoperability. + +7. Security Considerations + + These terms are frequently used to specify behavior with security + implications. The effects on security of not implementing a MUST or + SHOULD, or doing something the specification says MUST NOT or SHOULD + NOT be done may be very subtle. Document authors should take the time + to elaborate the security implications of not following + recommendations or requirements as most implementors will not have + had the benefit of the experience and discussion that produced the + specification. + +8. Acknowledgments + + The definitions of these terms are an amalgam of definitions taken + from a number of RFCs. In addition, suggestions have been + incorporated from a number of people including Robert Ullmann, Thomas + Narten, Neal McBurnett, and Robert Elz. + +9. Author's Address + + Scott Bradner + Harvard University + 1350 Mass. Ave. + Cambridge, MA 02138 + + phone - +1 617 495 3864 + + email - sob@harvard.edu + + + + + + +
\ No newline at end of file