2011-09-01 77 views
2

我目前正在写一个低级别的HTTP解析器和已经运行到了以下问题:拆分CRLF TCP有效载荷之间

我在包逐包基础上接收HTTP数据,即TCP有效载荷在一个一次。在解析这些数据时,我使用搜索CRLF的HTTP协议标准来描述标题行,块数据(在分块编码的情况下)以及用于从正文描绘标题的双CRLF。

我的问题是:我需要担心CRLF在两个TCP数据包有效载荷之间被拆分的可能性吗?例如,HTTP头将使用CRLFCRLF完成。两个后续TCP数据包可能有CR,然后是LFCRLF吗?

我假设是的;这是一个值得担心的情况,因为应用程序(HTTP)和TCP层是相互独立的。

任何洞察到这一点将不胜感激,谢谢!

回答

3

是的,CRLF可能会被拆分成不同的TCP数据包。试想一下,单个HTTP头比TCP MTU长一个字节的可能性。在那种情况下,CR只有空间,但不是NL。

所以不管你的代码有多棘手,它必须能够处理这种分裂的情况。

+0

绝对正确;你可以在“最”的时候做出假设,但捷径最终会赶上你。 – EricLaw

1

你在用什么语言工作?它没有为套接字提供某种形式的缓冲读取功能,所以你没有这个问题?

你的问题的简短答案是肯定的,理论上你不必担心它,因为有可能数据包会像那样到达。这是不太可能的,因为大多数HTTP端点倾向于在一个数据包中发送报头,并在后续数据包中发送主体。这不是惯例,更多的是大多数基于套接字的程序/语言的工作方式。

有一点需要记住的是,虽然协议标准对于CRLF分离非常明确,但许多实施HTTP(特别是客户端,但在某种程度上也是服务器)的人不知道/关心他们是什么正在做,不会遵守规则。他们会倾向于只用LF来分隔线条 - 特别是头部和身体之间的空白线条,我看到的代码段数量与我无法快速计算出来的问题有关。虽然这在技术上是违反协议的,但大多数服务器/客户端都会接受这种行为并解决此问题,因此您也需要这样做。

如果你不能做某种缓冲读取功能,有一些好消息。您只需将数据包一次读入内存并将数据标记到先前的数据包中。每次读取数据包时,扫描您的数据以查找双CRLF序列,如果没有找到它,请阅读下一个数据包,依次类推,直到找到头部的末端。这将是相对较小的内存使用情况,因为任何请求的头部不应该超过5-6KB,这给出了(平均)1450字节的以太网MTU意味着您不需要加载超过4或5个数据包进入内存来应对它。