我一直在尝试获取 picohttpparser工作,但我所有的努力都是徒劳的。我正在努力开始的基本上是将“手动”缓冲区传递给 picohttpparser 来解析它。这是来自官方项目页面的示例:
char buf[4096], *method, *path;
int pret, minor_version;
struct phr_header headers[100];
size_t buflen = 0, prevbuflen = 0, method_len, path_len, num_headers;
ssize_t rret;
while (1) {
/* read the request */
while ((rret = read(sock, buf + buflen, sizeof(buf) - buflen)) == -1 && errno == EINTR)
;
if (rret <= 0)
return IOError;
prevbuflen = buflen;
buflen += rret;
/* parse the request */
num_headers = sizeof(headers) / sizeof(headers[0]);
pret = phr_parse_request(buf, buflen, &method, &method_len, &path, &path_len,
&minor_version, headers, &num_headers, prevbuflen);
if (pret > 0)
break; /* successfully parsed the request */
else if (pret == -1)
return ParseError;
/* request is incomplete, continue the loop */
assert(pret == -2);
if (buflen == sizeof(buf))
return RequestIsTooLongError;
}
printf("request is %d bytes long\n", pret);
printf("method is %.*s\n", (int)method_len, method);
printf("path is %.*s\n", (int)path_len, path);
printf("HTTP version is 1.%d\n", minor_version);
printf("headers:\n");
for (i = 0; i != num_headers; ++i) {
printf("%.*s: %.*s\n", (int)headers[i].name_len, headers[i].name,
(int)headers[i].value_len, headers[i].value);
}
尽管如此,它涉及太多,我感到迷茫,所以我开始做一个简单的缓冲区,用这段代码传递给解析器:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "picohttpparser.h"
int main(int argc, char **argv)
{
/* simple buffer */
char rret[58]="GET /tutorials/other/top-20-mysql-best-practices/ HTTP/1.1";
/* parse the request */
phr_parse_request(rret, 58, "GET", 3);
return 0;
}
问题是我不断收到此错误:
parsebuf.c: In function ‘main’:
parsebuf.c:14:33: warning: passing argument 3 of ‘phr_parse_request’ from incompatible pointer type [-Wincompatible-pointer-types]
phr_parse_request(rret, 58, "GET", 3);
^~~~~
In file included from parsebuf.c:4:0:
picohttpparser.h:53:5: note: expected ‘const char **’ but argument is of type ‘char *’
int phr_parse_request(const char *buf, size_t len, const char **method, size_t *method_len, const char **path, size_t *path_len,
^~~~~~~~~~~~~~~~~
parsebuf.c:14:40: warning: passing argument 4 of ‘phr_parse_request’ makes pointer from integer without a cast [-Wint-conversion]
phr_parse_request(rret, 58, "GET", 3);
^
In file included from parsebuf.c:4:0:
picohttpparser.h:53:5: note: expected ‘size_t * {aka long unsigned int *}’ but argument is of type ‘int’
int phr_parse_request(const char *buf, size_t len, const char **method, size_t *method_len, const char **path, size_t *path_len,
^~~~~~~~~~~~~~~~~
parsebuf.c:14:5: error: too few arguments to function ‘phr_parse_request’
phr_parse_request(rret, 58, "GET", 3);
^~~~~~~~~~~~~~~~~
In file included from main.c:4:0:
picohttpparser.h:53:5: note: declared here
int phr_parse_request(const char *buf, size_t len, const char **method, size_t *method_len, const char **path, size_t *path_len,
^~~~~~~~~~~~~~~~~
我哪里可能错了?或者,是否有比项目网站上的例子更直接的例子?
最佳答案
我去了他们的 github 页面,这是他们在代码之前所说的:
The example below reads an HTTP request from socket
sock
usingread(2)
, parses it usingphr_parse_request
, and prints the details.
phr_parse_request
函数解析向服务器发出的请求,因此它需要
写什么样的请求(GET,POST,DELETE等),这就是为什么函数
需要一个 const char**
。
函数如下所示:
int phr_parse_request(const char *buf_start, size_t len, const char **method, size_t *method_len, const char **path,
size_t *path_len, int *minor_version, struct phr_header *headers, size_t *num_headers, size_t last_len)
参数都是指针,因为phr_parse_request
会改变where
这些变量 (method
, path
) 指向,这就是为什么你不需要
初始化它们或为其分配内存。
因此您必须像示例中那样声明变量:
int main(void)
{
char *method, *path;
size_t buflen = 0, method_len, path_len, num_headers;
struct phr_header headers[100];
int pret, minor_version;
char request[] = "GET /tutorials/other/top-20-mysql-best-practices/ HTTP/1.1\r\nHost: ....";
num_headers = sizeof(headers) / sizeof(headers[0]);
pret = phr_parse_request(request, strlen(request), &method, &method_len, &path, &path_len,
&minor_version, headers, &num_headers, 0);
if(pret > 0)
{
// success
// method has the request methid,
// method_len the length of (I presume they don't write the 0
// terminating byte
// etc.
}
...
}
唯一不明白的是prevbuflen
的意思,就是用
作为示例中的最后一个参数。可悲的是没有文件(或在
至少我找不到)。但是从bench.c
来看上的文件
存储库,该值可以为 0。查看 that file ,这就是“快速&
dirty”示例,而无需编写网络支持。将该文件用于
你的实验。
关于c - 将缓冲区传递给 picohttpparser 会导致编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49906017/