2013-03-02 89 views
5

我想写一个处理GET,POST,HEAD请求的小型C++ web服务器。我的问题是我不知道如何解析头文件,消息体等。它在套接字上侦听,我甚至可以将东西写入浏览器中,但我很好奇我应该如何在C++中执行此操作。如何解析C++中的http请求

据我所知标准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'分割请求并修剪它们吗(如果是的话)? 如何处理发布数据中的文件?

我想要实现的主要目标是获得一个包含header key => value对的向量,一个带请求方法的字符串,post数据(如在PHP中,如果存在的话)和查询字符串(/ index for例如)作为由'/'分割的字符串或向量。

谢谢!

+1

用C++来处理网络资料是一个矫枉过正的事情。但是,如果你真的想要走这么远,你最好准备好比这个更难的字符串操作。 – Shoe 2013-03-03 14:46:09

+2

如果你想解析HTTP消息,你需要问的唯一问题是...... *我必须阅读多少次[RFC 2616](http://www.w3.org/Protocols/rfc2616/rfc2616.html)在它全部陷入之前?* – rdlowrey 2013-03-04 13:48:43

+0

您是否想将自己的服务器编写为练习,还是希望**使用C++中的Web服务器库?在那种情况下,有非常好的解决方案 – 2013-04-19 15:38:41

回答

1

在自己做所有事情之前,我会为您介绍Poco,但您也应该阅读HTTP specification

类似下面:

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

是的,这基本上是字符串解析,然后响应创建追溯到浏览器,下面the specification

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

3

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

它并没有比这更简单。

+0

+1使用lambda函数! – yash101 2014-10-26 04:16:18

1

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