Passing a buffer to picohttpparser results in compile error

时间:2018-04-18 17:50:18

标签: c http parsing

I've been attempting to get picohttpparser to work yet all my exertion is futile. What I'm endeavoring to begin with is basically passing a "manual" buffer to picohttpparser to parse it. This is the example from the official project page:

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);
}

be that as it may, it's far excessively involved and I felt lost, so I started low by making a simple buffer to be passed to the parser with this code:

#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;
}

issue is I keep getting this error:

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,
     ^~~~~~~~~~~~~~~~~

where could I be conceivably wrong? alternatively, are there more straightforward examples than the one on the project site?

1 个答案:

答案 0 :(得分:1)

我去了他们的github页面,这就是他们在代码之前说的话:

  

下面的示例使用sock从套接字read(2)读取HTTP请求,使用phr_parse_request解析它,并打印详细信息。

函数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会改变位置 这些变量(methodpath)指向的,这就是您不需要的原因 初始化它们或为它分配内存。

所以你必须像在示例中那样声明变量:

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,&#34;快速&amp; 脏&#34;示例,无需编写网络支持。使用该文件 你的实验。