在C中解析HTTP请求行

Rya*_*yan 4 c webserver parsing request httprequest

这是永远不会结束的问题.任务是解析Web服务器中的请求行 - 具有不确定的长度 - 在C中.我将以下网络作为一个示例来处理.

GET /path/script.cgi?field1=value1&field2=value2 HTTP/1.1
Run Code Online (Sandbox Code Playgroud)

我必须提取绝对路径:/path/script.cgi和查询:?field1=value1&field2=value2.我被告知以下功能按住该键:strchr,strcpy,strncmp,strncpy,和/或strstr.

这是到目前为止发生的事情:我已经了解到使用类似的函数strchr并且strstr绝对允许我在某些点截断请求行,但绝不允许我删除我不想要的部分请求行,并且它无论我如何分层他们.

例如,这里有一些代码让我接近隔离查询,但我无法消除http版本.

bool parse(const char* line)
{
    // request line w/o method
    const char ch = '/';
    char* lineptr = strchr(line, ch);

    // request line w/ query and HTTP version
    char ch_1 = '?';
    char* lineptr_1 = strchr(lineptr, ch_1);

    // request line w/o query
    char ch_2 = ' ';
    char* lineptr_2 = strchr(lineptr_1, ch_2);

    printf("%s\n", lineptr_2);

    if (lineptr_2 != NULL)
        return true;
    else
        return false;
}
Run Code Online (Sandbox Code Playgroud)

毋庸置疑,我有一个类似的问题试图孤立绝对路径(我可以抛弃方法,但不能抛弃?或其后的任何东西),我认为没有机会我可以使用需要我知道先验的函数我想从一个位置(通常是一个数组)复制多少个字符到另一个位置,因为当实时运行时,我将无法预先知道请求行的样子.如果有人看到我失踪的东西,并指出我正确的方向,我将非常感激!

San*_*war 7

更优雅的解决方案.

#include <stdio.h>
#include <string.h>

int parse(const char* line)
{
    /* Find out where everything is */
    const char *start_of_path = strchr(line, ' ') + 1;
    const char *start_of_query = strchr(start_of_path, '?');
    const char *end_of_query = strchr(start_of_query, ' ');

    /* Get the right amount of memory */
    char path[start_of_query - start_of_path];
    char query[end_of_query - start_of_query];

    /* Copy the strings into our memory */
    strncpy(path, start_of_path,  start_of_query - start_of_path);
    strncpy(query, start_of_query, end_of_query - start_of_query);

    /* Null terminators (because strncpy does not provide them) */
    path[sizeof(path)] = 0;
    query[sizeof(query)] = 0;

    /*Print */
    printf("%s\n", query, sizeof(query));
    printf("%s\n", path, sizeof(path));
}

int main(void)
{
    parse("GET /path/script.cgi?field1=value1&field2=value2 HTTP/1.1");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)