【发布时间】:2020-04-26 19:44:05
【问题描述】:
我接到了一项任务,其中涉及使用 c++ 和 Boost Asio 库编写 Web 服务器。
我有一个工作服务器,它可以使用一本名为“Boost.Asio C++ Network Programming Cookbook”的书将 html 文件发送回客户端浏览器,但我在处理来自客户端的 POST 请求时遇到了困难。
当客户端连接到服务器时,他们会收到包含用户名和密码字段的简单 HTML 表单来登录服务器,然后使用 POST 请求将其发送到服务器。
我已经将收到的POST请求的内容输出到控制台,可以看到所有的header信息,但是看不到表单数据。我已经使用 Wireshark 来检查数据包,并且数据正在通过网络发送。
服务器以 Boost Asio 流缓冲区的形式接收数据,我正在解析它以获取请求的 HTML 文件,方法是将其读入向量,然后获取相关元素,例如方法或目标。
有人对在哪里寻找有关如何解析表单数据的教程有任何建议吗?
以下代码是解析 POST 请求并根据请求内容处理响应的 cpp 文件的一部分。 '&request' 参数是 Boost Asio 流缓冲
我在网络编程方面的经验很少,如果有任何建议,我将不胜感激!
解析请求的代码
// Prepare and return the response message.
// Parse the request from the client to find requested document
std::istream buffer(&request);
std::vector<std::string> parsed((std::istream_iterator<std::string>(buffer)), std::istream_iterator<std::string>() );
处理 POST 请求
else if (parsed.size() >= 3 && parsed[0] == "POST") {
htmlFile = "/files.html";
// Retrieve files from server file system. The second element in 'parsed' vector is file name
std::ifstream fileStream(".\\directory" + htmlFile);
// If the file exists then iterate it and assign the value to the content string variable, else return 404.
if (fileStream.good()) {
std::string fileContents((std::istreambuf_iterator<char>(fileStream)), std::istreambuf_iterator<char>());
content = fileContents;
code = "200 ok";
}
else {
std::ifstream fileStream(".\\directory\\404.html");
std::string fileContents((std::istreambuf_iterator<char>(fileStream)), std::istreambuf_iterator<char>());
content = fileContents;
code = "404";
}// End of nested if-else statement
}// End of else-if statement
else {
std::ifstream fileStream(".\\directory\\401.html");
std::string fileContents((std::istreambuf_iterator<char>(fileStream)), std::istreambuf_iterator<char>());
content = fileContents;
code = "401";
// Write bad request to log file for security audits if not "GET" request
logging.logAction("Illegal request by client IP " + m_sock->remote_endpoint().address().to_string());
}//End of if-else statement
std::ostringstream oss;
oss << "GET HTTP/1.1 " << code << " \r\n";
oss << "Cache-Control: no-cache, private" << "\r\n";
oss << "Content-Type: text/html" << "\r\n";
oss << "Content-Length: " << content.size() << "\r\n";
oss << "\r\n\r\n";
oss << content;
response = oss.str().c_str();
【问题讨论】:
-
您确定您阅读了帖子数据吗?您没有发布此代码。除此之外,请查看
boost::beast它包含一个示例webserver。 -
"I have used Wireshark to inspect the packets and the data is being sent over the network."- 不要使用 Wireshark。使用Fiddler 调试网络流量。 Wireshark 用于原始 TCP。 Fiddler 为 HTTP 流量提供了更好的诊断。 -
输出 post 数据的代码只是一个 for 循环,用于迭代称为 parsed 的向量。发布的代码目前缺少检查表单数据的逻辑,因为我还没有设法编写它
-
@selbie 谢谢,我会试试看我能找到什么!
-
请记住,TCP 是流协议,而不是消息协议。仅仅因为客户端对 1000 个字节进行了一次“发送”并不意味着您在服务器端相应的“Recv”将一次接收所有 1000 个字节。这是对套接字最常见的误解。
标签: c++ http server boost-asio