我目前正在编写一个低级HTTP解析器,并遇到了以下问题:
我在逐个数据包的基础上接收HTTP数据,即一次一个TCP有效负载。在解析这些数据时,我使用HTTP协议标准搜索CRLF来描述标题行,块数据(在分块编码的情况下),以及双重CRLF来描述来自正文的标题。
我的问题是:我是否需要担心CRLF在两个TCP数据包有效负载之间分裂的可能性?例如,HTTP标头将以CRLFCRLF结束。两个后续TCP数据包是否可能具有CR,然后是LFCRLF?
我假设是的;这是一个需要担心的情况,因为应用程序(HTTP)和TCP层相互独立。
非常感谢您对此的任何见解,谢谢!
答案 0 :(得分:3)
是的,CRLF可能会被拆分为不同的TCP数据包。只要想想单个HTTP标头比TCP MTU长一个字节的可能性。在这种情况下,CR只有空间,但不适用于NL。
所以无论你的代码有多棘手,它都必须能够处理这种分裂的情况。
答案 1 :(得分:1)
你在做什么语言?它是否没有针对套接字的某种形式的缓冲读取功能,因此您不会遇到此问题?
对你的问题的简短回答是肯定的,理论上你必须担心它,因为数据包可能会像那样到达。这是不太可能的,因为大多数HTTP端点倾向于在一个数据包和后续数据包中发送标头。按惯例而言,这一点较少,更多的是基于大多数基于套接字的程序/语言的工作方式。
要记住的一点是,尽管协议标准对于CRLF分离非常清楚,但许多实施HTTP的人(特别是客户端,但在某种程度上也是服务器)并不知道/关心什么他们正在做,不会遵守规则。他们倾向于只用LF分隔线 - 特别是头部和身体之间的空白线,我看到的这个问题的代码段数量我无法快速计算。虽然这在技术上是违反协议的,但大多数服务器/客户端都会接受此行为并解决它,因此您也需要这样做。
如果你不能做某种缓冲读取功能,那就有一些好消息。您需要做的就是一次将数据包读入内存并将数据标记到以前的数据包。每次读取数据包时,扫描数据以获得双CRLF序列,如果找不到,请读取下一个数据包,依此类推,直到找到头部结束。这将是相对较小的内存使用量,因为任何请求的头部都不应超过5-6KB,这给出了(平均值)1450字节的以太网MTU意味着您不应该需要加载超过4或5个数据包进入内存来应对它。