feat: 初步封装了 HTTP 协议请求和响应体
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
file(GLOB_RECURSE HEADER_FILE ${CMAKE_CURRENT_SOURCE_DIR}/*/*.cpp)
|
||||
file(GLOB_RECURSE SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/*/*.cpp)
|
||||
|
||||
add_library(ouc_server_lib ${SOURCE_FILE} ${HEADER_FILE})
|
||||
|
||||
target_include_directories(ouc_server_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
@@ -0,0 +1,53 @@
|
||||
#include <http/http_method_type.hpp>
|
||||
|
||||
namespace ouc_server
|
||||
{
|
||||
namespace http
|
||||
{
|
||||
HttpMethodType str2type(const std::string &str)
|
||||
{
|
||||
if (str == "GET")
|
||||
return HttpMethodType::Get;
|
||||
else if (str == "HEAD")
|
||||
return HttpMethodType::Head;
|
||||
else if (str == "POST")
|
||||
return HttpMethodType::Post;
|
||||
else if (str == "PUT")
|
||||
return HttpMethodType::Put;
|
||||
else if (str == "DELETE")
|
||||
return HttpMethodType::Delete;
|
||||
else if (str == "CONNECT")
|
||||
return HttpMethodType::Connect;
|
||||
else if (str == "OPTIONS")
|
||||
return HttpMethodType::Options;
|
||||
else if (str == "TRACE")
|
||||
return HttpMethodType::Trace;
|
||||
else
|
||||
return HttpMethodType::Get;
|
||||
}
|
||||
|
||||
std::string type2str(HttpMethodType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case HttpMethodType::Get:
|
||||
default:
|
||||
return "GET";
|
||||
case HttpMethodType::Head:
|
||||
return "HEAD";
|
||||
case HttpMethodType::Post:
|
||||
return "POST";
|
||||
case HttpMethodType::Put:
|
||||
return "PUT";
|
||||
case HttpMethodType::Delete:
|
||||
return "DELETE";
|
||||
case HttpMethodType::Connect:
|
||||
return "CONNECT";
|
||||
case HttpMethodType::Options:
|
||||
return "OPTIONS";
|
||||
case HttpMethodType::Trace:
|
||||
return "TRACE";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef INCLUDE_OUC_SERVER_HTTP_METHOD_TYPE
|
||||
#define INCLUDE_OUC_SERVER_HTTP_METHOD_TYPE
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ouc_server
|
||||
{
|
||||
namespace http
|
||||
{
|
||||
enum class HttpMethodType
|
||||
{
|
||||
Get,
|
||||
Head,
|
||||
Post,
|
||||
Put,
|
||||
Delete,
|
||||
Connect,
|
||||
Options,
|
||||
Trace
|
||||
};
|
||||
|
||||
HttpMethodType str2type(const std::string &);
|
||||
|
||||
std::string type2str(HttpMethodType);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // INCLUDE_OUC_SERVER_HTTP_METHOD_TYPE
|
||||
@@ -0,0 +1,91 @@
|
||||
#include <http/http_request.hpp>
|
||||
|
||||
namespace ouc_server
|
||||
{
|
||||
namespace http
|
||||
{
|
||||
HttpRequest HttpRequest::from_string(const std::string &raw_str)
|
||||
{
|
||||
std::istringstream iss(raw_str);
|
||||
HttpRequest req;
|
||||
|
||||
parse_top_line(req, iss);
|
||||
switch (req.method)
|
||||
{
|
||||
case HttpMethodType::Get:
|
||||
default:
|
||||
parse_get_request(req, iss);
|
||||
break;
|
||||
|
||||
case HttpMethodType::Head:
|
||||
break;
|
||||
case HttpMethodType::Post:
|
||||
break;
|
||||
case HttpMethodType::Put:
|
||||
break;
|
||||
case HttpMethodType::Delete:
|
||||
break;
|
||||
case HttpMethodType::Connect:
|
||||
break;
|
||||
case HttpMethodType::Options:
|
||||
break;
|
||||
case HttpMethodType::Trace:
|
||||
break;
|
||||
}
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
void HttpRequest::parse_top_line(HttpRequest &req, std::istringstream &iss)
|
||||
{
|
||||
std::string line, type_str;
|
||||
std::getline(iss, line);
|
||||
|
||||
while ((!line.empty()) && line.back() != '\r')
|
||||
line.pop_back();
|
||||
|
||||
std::istringstream req_iss(line);
|
||||
|
||||
req_iss >> type_str >> req.path >> req.version;
|
||||
req.method = str2type(type_str);
|
||||
}
|
||||
|
||||
void HttpRequest::parse_get_request(HttpRequest &req, std::istringstream &iss)
|
||||
{
|
||||
std::string line;
|
||||
|
||||
// parse top line
|
||||
std::getline(iss, line);
|
||||
while ((!line.empty()) && line.back() != '\r')
|
||||
line.pop_back();
|
||||
std::istringstream req_iss(line);
|
||||
std::string type_str;
|
||||
req_iss >> type_str >> req.path >> req.version;
|
||||
req.method = str2type(type_str);
|
||||
|
||||
// parse headers
|
||||
while (std::getline(iss, line) && line != "\r")
|
||||
{
|
||||
while ((!line.empty()) && line.back() == '\r')
|
||||
line.pop_back();
|
||||
|
||||
auto pos = line.find(": ");
|
||||
if (pos == std::string::npos)
|
||||
pos = line.find(":");
|
||||
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
std::string key = line.substr(0, pos);
|
||||
std::string val = line.substr(pos + 2);
|
||||
req.headers[key] = val;
|
||||
}
|
||||
}
|
||||
|
||||
// parse body (not finish)
|
||||
std::string body;
|
||||
while (std::getline(iss, line))
|
||||
body += line + "\n";
|
||||
req.body = body;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,28 +2,33 @@
|
||||
#define INCLUDE_OUC_SERVER_HTTP_REQUEST
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <sstream>
|
||||
|
||||
#include <http/http_method_type.hpp>
|
||||
|
||||
namespace ouc_server
|
||||
{
|
||||
namespace http
|
||||
{
|
||||
enum class HttpMethodType
|
||||
{
|
||||
Get,
|
||||
Head,
|
||||
Post,
|
||||
Put,
|
||||
Delete,
|
||||
Connect,
|
||||
Options,
|
||||
Trace
|
||||
};
|
||||
|
||||
struct HttpRequest
|
||||
{
|
||||
HttpMethodType method;
|
||||
HttpMethodType method = HttpMethodType::Get;
|
||||
std::string path;
|
||||
std::string version;
|
||||
|
||||
std::unordered_map<std::string, std::string> headers;
|
||||
std::string body;
|
||||
|
||||
static HttpRequest from_string(const std::string &);
|
||||
|
||||
private:
|
||||
static void parse_top_line(HttpRequest &, std::istringstream &);
|
||||
|
||||
static void parse_get_request(HttpRequest &, std::istringstream &);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // INCLUDE_OUC_SERVER_HTTP_REQUEST
|
||||
@@ -0,0 +1,27 @@
|
||||
#include <http/http_response.hpp>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace ouc_server
|
||||
{
|
||||
namespace http
|
||||
{
|
||||
std::string HttpResponse::to_string() const
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << version << " "
|
||||
<< stus_code << " "
|
||||
<< stus_msg << "\r\n";
|
||||
|
||||
for (auto &[k, v] : headers)
|
||||
oss << k << ": " << v << "\r\n";
|
||||
|
||||
oss << "\r\n"
|
||||
<< body;
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
HttpResponseBuilder HttpResponse::create() { return {}; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
#ifndef INCLUDE_OUC_SERVER_HTTP_RESPONSE
|
||||
#define INCLUDE_OUC_SERVER_HTTP_RESPONSE
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <http/http_method_type.hpp>
|
||||
|
||||
namespace ouc_server
|
||||
{
|
||||
namespace http
|
||||
{
|
||||
class HttpResponseBuilder;
|
||||
|
||||
struct HttpResponse
|
||||
{
|
||||
std::string version = "HTTP/1.1";
|
||||
int stus_code = 200;
|
||||
std::string stus_msg = "OK";
|
||||
|
||||
std::unordered_map<std::string, std::string> headers;
|
||||
std::string body;
|
||||
|
||||
std::string to_string() const;
|
||||
|
||||
static HttpResponseBuilder create();
|
||||
};
|
||||
|
||||
class HttpResponseBuilder
|
||||
{
|
||||
private:
|
||||
HttpResponse res;
|
||||
|
||||
public:
|
||||
HttpResponseBuilder() = default;
|
||||
~HttpResponseBuilder() = default;
|
||||
|
||||
HttpResponse build() { return res; }
|
||||
|
||||
public:
|
||||
HttpResponseBuilder &version(const std::string &p_version)
|
||||
{
|
||||
res.version = p_version;
|
||||
return *this;
|
||||
}
|
||||
|
||||
HttpResponseBuilder &stus_code(int p_stus_code)
|
||||
{
|
||||
res.stus_code = p_stus_code;
|
||||
return *this;
|
||||
}
|
||||
|
||||
HttpResponseBuilder &stus_msg(const std::string &p_stus_msg)
|
||||
{
|
||||
res.stus_msg = p_stus_msg;
|
||||
return *this;
|
||||
}
|
||||
|
||||
HttpResponseBuilder &header(const std::pair<const std::string &, const std::string &> p_header)
|
||||
{
|
||||
res.headers.insert(p_header);
|
||||
return *this;
|
||||
}
|
||||
|
||||
HttpResponseBuilder &header(const std::string &p_key, const std::string &p_value)
|
||||
{
|
||||
return header({p_key, p_value});
|
||||
}
|
||||
|
||||
HttpResponseBuilder &body(const std::string &p_body)
|
||||
{
|
||||
res.body = p_body;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // INCLUDE_OUC_SERVER_HTTP_RESPONSE
|
||||
Reference in New Issue
Block a user