c++ - 如何正确解析传入的 HTTP 请求

标签 c++ http parsing winsock

我已经使用 WinSck 创建了一个 C++ 应用程序,它实现了一个小型(仅处理我需要的一些功能)http 服务器。这用于使用 http 请求与外界通信。它可以工作,但有时请求没有得到正确处理,因为解析失败。现在我很确定请求的格式正确,因为它们是由主要的网络浏览器发送的,例如 firefox/chrome 或 perl/C#(具有 http 模块/dll)。

经过一些调试,我发现问题实际上是在接收消息上。当消息不止一个部分出现时(它不是在一次 recv() 调用中读取的),有时解析会失败。我已经多次尝试解决这个问题,但似乎没有什么是足够可靠的。

我现在做的是读入数据,直到找到 "\r\n\r\n" 指示 header 结束的序列。如果 WSAGetLastError() 在发现这样的序列之前报告了 10035 之外的其他内容(连接关闭/失败),我将丢弃该消息。当我知道我有整个标题时,我会解析它并查找有关正文长度的信息。但是我不确定这个信息是否是强制性的(我认为不是),如果没有这样的信息我该怎么办 - 这是否意味着没有尸体?另一个问题是我不知道是否应该在正文之后寻找 "\r\n\r\n"(如果它的长度大于零)。

有人知道如何可靠地解析 http 消息吗?

注意:我知道那里有 http 服务器的实现。由于各种原因,我想要自己的。是的,重新发明轮子是不好的,我也知道这一点。

最佳答案

如果您打算编写自己的解析器,我会选择 Zed Shaw方法:使用Ragel状态机编译器并基于它构建你的解析器。如果你小心的话,Ragel 可以处理成 block 的输入。

不过,老实说,我只会使用 something like this .

您的首选资源应该是 RFC 2616 ,它描述了 HTTP 1.1,您可以使用它来构建解析器。祝你好运!

关于c++ - 如何正确解析传入的 HTTP 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3698402/

相关文章:

c++ - 声明的含义是什么,例如无效a(字符串b = 0)

android - Apache 2.4.6 - 发送 GZIP 内容有时会导致 "read more bytes of request body than expected"

parsing - attoparsec 错误解析 double

Javascript - 用对象值替换字符串中的单词

java - 如果 http 请求的内容类型是 urlencoded,如何让 Spring Boot Controller 读取对对象的 http 请求正文?

getParseData 的反转 : from parsed code back to code

c++ - 使用多个 gSOAP 实现时的重新定义错误

c++ - Ubuntu 将可执行文件识别为共享库,并且不会通过单击来运行它

c++ - MPI_Scatterv 仅分散自定义 MPI_Datatype 的一部分

java - 提交 GET 或 POST 以在 ElasticSearch 中搜索