1.15.C++ project: Design of HttpRequest and HttpResponse modules that imitate muduo library to implement concurrent server

Article directory

  • 1. HttpRequest module
  • 2. HttpResponse module
  • 3. Realize ideas
    • (1) Function
    • (2) Meaning
  • 4. Code

1. HttpRequest module

2. HttpResponse module

3. Implement ideas

(1) Function

  • HttpRequest module
    Store HTTP request information
    Receive a piece of data, parse it according to the HTTP request format, and get each key element and put it in the Request.
  • HttpResponse module
    Store HTTP response information
    While performing business processing, let the user fill in the response elements in the Response. After completion, organize it into data in HTTP response format and send it to the client.

(2) Meaning

  • HttpRequest module
    Make the analysis of HTTP requests easier
  • HttpResponse module
    Make the HTTP response process simple

4. Code

  • HttpRequest module
class HttpRequest {<!-- -->
    public:
        std::string _method; //Request method
        std::string _path; //Resource path
        std::string _version; //Protocol version
        std::string _body; //Request body
        std::smatch _matches; //Regular extraction data of resource path
        std::unordered_map<std::string, std::string> _headers; //Header field
        std::unordered_map<std::string, std::string> _params; //query string
    public:
        HttpRequest():_version("HTTP/1.1") {<!-- -->}
        void ReSet() {<!-- -->
            _method.clear();
            _path.clear();
            _version = "HTTP/1.1";
            _body.clear();
            std::smatch match;
            _matches.swap(match);
            _headers.clear();
            _params.clear();
        }
        //Insert header field
        void SetHeader(const std::string & amp;key, const std::string & amp;val) {<!-- -->
            _headers.insert(std::make_pair(key, val));
        }
        //Determine whether the specified header field exists
        bool HasHeader(const std::string & amp;key) const {<!-- -->
            auto it = _headers.find(key);
            if (it == _headers.end()) {<!-- -->
                return false;
            }
            return true;
        }
        //Get the value of the specified header field
        std::string GetHeader(const std::string & amp;key) const {<!-- -->
            auto it = _headers.find(key);
            if (it == _headers.end()) {<!-- -->
                return "";
            }
            return it->second;
        }
        //Insert query string
        void SetParam(const std::string & amp;key, const std::string & amp;val) {<!-- -->
            _params.insert(std::make_pair(key, val));
        }
        //Determine whether there is a specified query string
        bool HasParam(const std::string & amp;key) const {<!-- -->
            auto it = _params.find(key);
            if (it == _params.end()) {<!-- -->
                return false;
            }
            return true;
        }
        //Get the specified query string
        std::string GetParam(const std::string & amp;key) const {<!-- -->
            auto it = _params.find(key);
            if (it == _params.end()) {<!-- -->
                return "";
            }
            return it->second;
        }
        //Get the text length
        size_t ContentLength() const {<!-- -->
            // Content-Length: 1234\r\\

            bool ret = HasHeader("Content-Length");
            if (ret == false) {<!-- -->
                return 0;
            }
            std::string clen = GetHeader("Content-Length");
            return std::stol(clen);
        }
        //Determine whether it is a short link
        bool Close() const {<!-- -->
            // If there is no Connection field, or if there is a Connection but the value is close, it is a short link, otherwise it is a long connection.
            if (HasHeader("Connection") == true & amp; & amp; GetHeader("Connection") == "keep-alive") {<!-- -->
                return false;
            }
            return true;
        }
};
  • HttpResponse module
class HttpResponse {<!-- -->
    public:
        int _statu;
        bool _redirect_flag;
        std::string _body;
        std::string _redirect_url;
        std::unordered_map<std::string, std::string> _headers;
    public:
        HttpResponse():_redirect_flag(false), _statu(200) {<!-- -->}
        HttpResponse(int statu):_redirect_flag(false), _statu(statu) {<!-- -->}
        void ReSet() {<!-- -->
            _statu = 200;
            _redirect_flag = false;
            _body.clear();
            _redirect_url.clear();
            _headers.clear();
        }
        //Insert header field
        void SetHeader(const std::string & amp;key, const std::string & amp;val) {<!-- -->
            _headers.insert(std::make_pair(key, val));
        }
        //Determine whether the specified header field exists
        bool HasHeader(const std::string & amp;key) {<!-- -->
            auto it = _headers.find(key);
            if (it == _headers.end()) {<!-- -->
                return false;
            }
            return true;
        }
        //Get the value of the specified header field
        std::string GetHeader(const std::string & amp;key) {<!-- -->
            auto it = _headers.find(key);
            if (it == _headers.end()) {<!-- -->
                return "";
            }
            return it->second;
        }
        void SetContent(const std::string & amp;body, const std::string & amp;type = "text/html") {<!-- -->
            _body = body;
            SetHeader("Content-Type", type);
        }
        void SetRedirect(const std::string & amp;url, int status = 302) {<!-- -->
            _statu = status;
            _redirect_flag = true;
            _redirect_url = url;
        }
        //Determine whether it is a short link
        bool Close() {<!-- -->
            // If there is no Connection field, or if there is a Connection but the value is close, it is a short link, otherwise it is a long connection.
            if (HasHeader("Connection") == true & amp; & amp; GetHeader("Connection") == "keep-alive") {<!-- -->
                return false;
            }
            return true;
        }
};