【问题标题】:how to parse http request in c++如何在 C++ 中解析 http 请求
【发布时间】:2013-03-02 21:03:13
【问题描述】:

我正在尝试编写一个小型 c++ 网络服务器来处理 GET、POST、HEAD 请求。我的问题是我不知道如何解析标头、消息正文等。它正在侦听套接字,我什至可以将内容写到浏览器中,但我很好奇我应该如何在 c++ 中执行此操作。

Afaik 标准 GET/POST 请求应如下所示:

GET /index HTTP/1.1
Host: 192.168.0.199:80
Connection: keep-alive
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.22 (KHTML, like Gecko)     Chrome/25.0.1364.97 Safari/537.22
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

this is the message body

所有行都以 '\r\n' 结尾。

我是否应该在 '\n' 处拆分请求并修剪它们(如果可以,如何修剪)? 还有如何处理post数据中的文件?

我想要实现的主要目标是获取一个包含标头键=>值对的向量、一个带有请求方法的字符串、发布数据(如在 PHP 中,如果它存在)和查询字符串(例如 /index ) 作为字符串或向量,由 '/' 分割。

谢谢!

【问题讨论】:

  • 使用 C++ 处理 Web 内容是一种矫枉过正。但如果你真的想走那么远,你最好准备好接受比这更难的字符串操作。
  • 如果你想解析 HTTP 消息,你唯一需要问的问题是...... 我必须阅读RFC 2616 多少次才能完全理解?
  • 您想编写自己的服务器作为练习,还是想使用 C++ 中的 Web 服务器库?在这种情况下,有很好的解决方案

标签: c++ parsing http


【解决方案1】:

在自己动手之前,先介绍一下Poco

class MyHTTPRequestHandler : public HTTPRequestHandler
{
public:
    virtual void handleRequest(HTTPServerRequest & request,
                               HTTPServerResponse & response) {
        // Write your HTML response in res object
    }
};

class MyRequestHandlerFactory : public HTTPRequestHandlerFactory
{
    MyHTTPRequestHandler handler;

public:
    MyRequestHandlerFactory(){}
    HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request)
    {
        const string method = request.getMethod();
        if (method == "get" || method == "post")
            return &handler;
        return 0;
    }
};

int main()
{
    HTTPServerParams params;
    params.setMaxQueued(100);
    params.setMaxThreads(16);
    ServerSocket svs(80);
    MyRequestHandlerFactory factory;
    HTTPServer srv(&factory, svs, &params);
    srv.start();
    while (true)
        Thread::sleep(1000);
}

【讨论】:

    【解决方案2】:

    Boost.Asio 是一个很好的库,但相对低级。你真的很想使用更高级别的库。 There’s a modern C++ library called node.native 你应该去看看。一个非常服务器可以实现如下:

    #include <iostream>
    #include <native/native.h>
    using namespace native::http;
    
    int main() {
        http server;
        if(!server.listen("0.0.0.0", 8080, [](request& req, response& res) {
            res.set_status(200);
            res.set_header("Content-Type", "text/plain");
            res.end("C++ FTW\n");
        })) return 1; // Failed to run server.
    
        std::cout << "Server running at http://0.0.0.0:8080/" << std::endl;
        return native::run();
    }
    

    没有比这更简单的了。

    【讨论】:

      【解决方案3】:

      是的,这基本上只是字符串解析,然后在the specification 之后创建返回到浏览器的响应。

      但是,如果这不仅仅是一个爱好项目,并且您不想承担非常大的任务,那么您应该使用 Apache,如果您需要一个需要扩展的 Web 服务器,或者tntnet,如果您需要一个c++ web 框架,或者cpp-netlib,如果你需要 C++ 网络的东西。

      【讨论】:

        【解决方案4】:

        您可能需要考虑Proxygen,Facebook 的 C++ HTTP 框架。它是在 BSD 许可下开源的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-08-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-29
          相关资源
          最近更新 更多