我有一个数据包捕获代码,可将 http 有效负载写入文件。现在我想从这些转储中提取 URL 信息。对于每个数据包,有效负载都是这样开始的。
GET /intl/en_com/images/logo_plain.png HTTP/1.1..主机:www.google.co.in..用户代理:Mozilla/5.0
我想提取:
- “GET”和“HTTP/1.1”之间的字符串
- “Host:”和“User-Agent”之间的字符串
如何在 C 中做到这一点?是否有任何内置的字符串函数?还是正则表达式?
我有一个数据包捕获代码,可将 http 有效负载写入文件。现在我想从这些转储中提取 URL 信息。对于每个数据包,有效负载都是这样开始的。
GET /intl/en_com/images/logo_plain.png HTTP/1.1..主机:www.google.co.in..用户代理:Mozilla/5.0
我想提取:
如何在 C 中做到这一点?是否有任何内置的字符串函数?还是正则表达式?
C 没有内置的正则表达式,虽然库可用:http://www.arglist.com/regex/,http://www.pcre.org/是我最常看到的两个。
对于这么简单的任务,您无需使用正则表达式即可轻松摆脱困境。如果这些行都小于某个最大长度MAXLEN,则一次只处理一行:
char buf[MAXLEN];
char url[MAXLEN];
char host[MAXLEN];
int state = 0; /* 0: Haven't seen GET yet; 1: haven't seen Host yet */
FILE *f = fopen("my_input_file", "rb");
if (!f) {
report_error_somehow();
}
while (fgets(buf, sizeof buf, f)) {
/* Strip trailing \r and \n */
int len = strlen(buf);
if (len >= 2 && buf[len - 1] == '\n' && buf[len - 2] == '\r') {
buf[len - 2] = 0;
} else {
if (feof(f)) {
/* Last line was not \r\n-terminated: probably OK to ignore */
} else {
/* Either the line was too long, or ends with \n but not \r\n. */
report_error_somehow();
}
}
if (state == 0 && !memcmp(buf, "GET ", 4)) {
strcpy(url, buf + 4); /* We know url[] is big enough */
++state;
} else if (state == 1 && !memcmp(buf, "Host: ", 6)) {
strcpy(host, buf + 6); /* We know host[] is big enough */
break;
}
}
fclose(f);
该解决方案不需要像 KennyTM 的回答那样将整个文件缓冲在内存中(尽管如果您知道文件很小,这很好)。请注意,我们使用fgets()而不是 unsafe gets(),这很容易在长行上溢出缓冲区。
寻找\r使用strchr(或strstr)的位置。由于字符串GETandHTTP/1.1和Host:是固定长度的,因此可以轻松提取其间路径的索引和位置。
如果你想使用正则表达式,在 POSIX 兼容的系统上有regcomp(3),但这也很难使用。