在不使用regexp的情况下解析HTTP请求

Mar*_*les 4 c++ string parsing httprequest

我正在使用正则表达式来分隔HTTP请求的字段:

GET /index.asp?param1=hello&param2=128 HTTP/1.1
Run Code Online (Sandbox Code Playgroud)

这条路:

smatch m;
try 
{ 
    regex re1("(GET|POST) (.+) HTTP"); 
    regex_search(query, m, re1); 
} 
catch (regex_error e) 
{ 
    printf("Regex 1 Error: %d\n", e.code()); 
}
string method = m[1]; 
string path = m[2];

try 
{ 
    regex re2("/(.+)?\\?(.+)?"); 
    if (regex_search(path, m, re2)) 
    { 
        document = m[1]; 
        querystring = m[2];
    }
} 
catch (regex_error e) 
{ 
    printf("Regex 2 Error: %d\n", e.code()); 
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,这段代码适用于MSVC,但不适用于GCC 4.8.2(我在Ubuntu Server 14.04上使用).你能否建议使用普通的std :: string运算符分割该字符串的不同方法?

我不知道如何在不同的元素中拆分URL,因为查询字符串分隔符'?' 字符串可能存在也可能不存在.

Gal*_*lik 7

你可能会std::istringstream用来解析这个:

int main()
{
    std::string request = "GET /index.asp?param1=hello&param2=128 HTTP/1.1";

    // separate the 3 main parts

    std::istringstream iss(request);

    std::string method;
    std::string query;
    std::string protocol;

    if(!(iss >> method >> query >> protocol))
    {
        std::cout << "ERROR: parsing request\n";
        return 1;
    }

    // reset the std::istringstream with the query string

    iss.clear();
    iss.str(query);

    std::string url;

    if(!std::getline(iss, url, '?')) // remove the URL part
    {
        std::cout << "ERROR: parsing request url\n";
        return 1;
    }

    // store query key/value pairs in a map
    std::map<std::string, std::string> params;

    std::string keyval, key, val;

    while(std::getline(iss, keyval, '&')) // split each term
    {
        std::istringstream iss(keyval);

        // split key/value pairs
        if(std::getline(std::getline(iss, key, '='), val))
            params[key] = val;
    }

    std::cout << "protocol: " << protocol << '\n';
    std::cout << "method  : " << method << '\n';
    std::cout << "url     : " << url << '\n';

    for(auto const& param: params)
        std::cout << "param   : " << param.first << " = " << param.second << '\n';
}
Run Code Online (Sandbox Code Playgroud)

输出:

protocol: HTTP/1.1
method  : GET
url     : /index.asp
param   : param1 = hello
param   : param2 = 128
Run Code Online (Sandbox Code Playgroud)