当我使用 strtok_r(buff, " \r\n", &saveptr); 时,从浏览器请求中提取内容的过程是什么?

What is process of extract things from browser request when I use strtok_r(buff, " \r\n", &saveptr);?

假设我已在线读取浏览器请求并将其保存到 buff。我想从这个 buff 中提取一些信息,比如 method、url、versoin。所以我想用strtok_r拆分。

假设请求是 "GET http://******** HTTP/1.1"。 ********* 是一个网站 link。我设置了某个令牌,并使用以下代码:

cmd = strtok_r(buf1, token, &saveptr);
strcpy(url, strtok_r(NULL, token, &saveptr));
version = strtok_r(NULL, token, &saveptr);

首先,如果我将令牌设置为“”。然后,我会得到cmd="GET",url = "http://********"。但是,VERSION后面没有“”。所以这可能会导致问题。

其次,如果我将令牌设置为“\r\n”。然后,我会得到cmd="GET http://******** HTTP/1.1",这是错误的

所以正确的方法可能是将token设置为“\r\n”。但我不确定这个过程。谁能解释为什么这有效???

这里有两件事要提。

  1. 您可以将包含多个分隔符的数组传递给 strtok()/strtok_r()。在解析标记时,它将考虑分隔符数组中的 each 元素。来自man page[强调我的]

The delim argument specifies a set of bytes that delimit the tokens in the parsed string.

A sequence of two or more contiguous delimiter bytes in the parsed string is considered to be a single delimiter.

  1. strcpy(url, strtok_r(NULL, token, &saveptr)); 这是一种非常危险的代码编写方式。如果 strtok() 失败并且 return 为 NULL,请考虑 恐怖 。最好的方法是在另一个变量中收集 strtok() 的 return 值,并在 NULL 检查后,将该变量用于 strcpy().

strtok(和系列)的工作原理是消除第一个字符串中恰好出现在第二个字符串中的所有字符(单个字符,而不是序列),并为您提供第一个字符串的指针 not 使其任何字符出现在第二个字符串上。它在历史上曾用在 shell sh(1) 中,它使用 IFS 环境变量的内容来划分输入字符串并构造 argv 传递给程序的字符串数组 exec(2).

顺便说一下,strtok(3) 和 cousings 使用的算法不足以解析 HTTP 输入,因为您需要分几步进行解析(一次,使用行定界符在行边界划分输入缓冲区,至少一秒钟将行划分为参数---以space作为第二个参数)

要解析http协议最好开发一个特定的解析器o使用语言解析技术来扫描东西。有关此类实用程序的帮助,请参阅 flex(1)bison(1),长期以来一直是 unix 系统的标准。